2016-08-10 5 views
2

데이터가있는 일반적인 테이블이 있습니다 (예 : mytemptable). 내 SELECT 쿼리에서PostgreSQL, 한 번에 두 개의 윈도우 함수

DROP TABLE IF EXISTS mytemptable; 
CREATE TEMP TABLE mytemptable 
     (mydate date, somedoc text, inqty int, outqty int); 
INSERT INTO mytemptable (mydate, somedoc, inqty, outqty) 
VALUES ('01.01.2016.', '123-13-24', 3, 0), 
     ('04.01.2016.', '15-19-44', 2, 0), 
     ('06.02.2016.', '15-25-21', 0, 1), 
     ('04.01.2016.', '21-133-12', 0, 1), 
     ('04.01.2016.', '215-11-51', 0, 2), 
     ('05.01.2016.', '11-181-01', 0, 1), 
     ('05.02.2016.', '151-80-8', 4, 0), 
     ('04.01.2016.', '215-11-51', 0, 2), 
     ('07.02.2016.', '34-02-02', 0, 2); 

SELECT row_number() OVER(ORDER BY mydate) AS rn, 
     mydate, somedoc, inqty, outqty, 
     SUM(inqty-outqty) OVER(ORDER BY mydate) AS csum 
    FROM mytemptable 
ORDER BY mydate; 

나는 날짜별로 결과를 주문하고 행 번호 'RN'누적 (통과) 합 'CSUM'을 추가하려고합니다. 물론 실패합니다.
나는 어떤 식 으로든 충돌하는 쿼리에서 두 개의 윈도우 함수를 사용하기 때문에 이것이라고 생각합니다. 제대로이 쿼리는 명령을 잘, 빨리 할 수 ​​있도록하고 'CSUM'열에서 적절한 결과를 얻으려면 어떻게

(3, 5, 4, 2, 0, -1, 3, 2, 0)

답변

2

2016-04-01에 정렬 순서가 있기 때문에 해당 행의 결과는 총 누적 합계가됩니다. 다른 값을 사용하려면 order by 열을 사용하십시오.

From the manual

:

윈도우 함수와 관련된 또 다른 중요한 개념이 있습니다

: 각 행에 대해, 그 파티션은 윈도우 프레임이라고 내에서 행의 세트가있다. 대부분의 (그러나 전부는 아님) 창 함수는 전체 파티션이 아닌 창 프레임의 행에서만 작동합니다. 기본적으로 ORDER BY가 제공되면 프레임은 파티션 시작부터 현재 행까지의 모든 행과 ORDER BY 절에 따라 현재 행과 동일한 모든 행으로 구성됩니다. ORDER BY는 untieing 열없이 파티션

의 기본 프레임은 모든 행으로 구성 생략하면 당신은 외부 쿼리에서 생성 된 행 번호를 사용할 수 있습니다 매우 과학적인 소리

set datestyle = 'dmy'; 
with mytemptable (mydate, somedoc, inqty, outqty) as (
    values 
    ('01-01-2016'::date, '123-13-24', 3, 0), 
    ('04-01-2016', '15-19-44', 2, 0), 
    ('06-02-2016', '15-25-21', 0, 1), 
    ('04-01-2016', '21-133-12', 0, 1), 
    ('04-01-2016', '215-11-51', 0, 2), 
    ('05-01-2016', '11-181-01', 0, 1), 
    ('05-02-2016', '151-80-8', 4, 0), 
    ('04-01-2016', '215-11-51', 0, 2), 
    ('07-02-2016', '34-02-02', 0, 2) 
) 
select *, sum(inqty-outqty) over(order by mydate, rn) as csum 
from (
    select 
     row_number() over(order by mydate) as rn, 
     mydate, somedoc, inqty, outqty 
    from mytemptable 
) s 
order by mydate; 
rn | mydate | somedoc | inqty | outqty | csum 
----+------------+-----------+-------+--------+------ 
    1 | 2016-01-01 | 123-13-24 |  3 |  0 | 3 
    2 | 2016-04-01 | 15-19-44 |  2 |  0 | 5 
    3 | 2016-04-01 | 21-133-12 |  0 |  1 | 4 
    4 | 2016-04-01 | 215-11-51 |  0 |  2 | 2 
    5 | 2016-04-01 | 215-11-51 |  0 |  2 | 0 
    6 | 2016-05-01 | 11-181-01 |  0 |  1 | -1 
    7 | 2016-05-02 | 151-80-8 |  4 |  0 | 3 
    8 | 2016-06-02 | 15-25-21 |  0 |  1 | 2 
    9 | 2016-07-02 | 34-02-02 |  0 |  2 | 0 
+0

합니다. 그러나 당신은 내 것과 같은 결과를 얻습니다. 정확하지 않거나 바람직하지 않습니다. 두 개의 쿼리를 사용하여 원하는 결과를 얻을 수 있습니다. 먼저 행 번호를 추가 한 다음 두 번째로 ORDER BY rn, mydate를 추가합니다. 그러나 나는 아마 하나의 쿼리로 이것을 할 수도있다. 실제 데이터가 크고 성능이 중요합니다. – user1697111

+0

@ user1697111 –

+0

콜로라도에 감사드립니다. 이것은 해결책으로 보인다. 이제 나는 그것을 연구해야한다. 그러나 예상대로 결과가 나옵니다. 필자는 필자의 시스템과 pgAdmin III 라인에서 "date date = 'dmy'설정; 구문 오류가 발생합니다. 나는 ":: date"도 캐스팅하지 않고 eurpoean 스타일로 날짜를 쓸 수있다. 이 쿼리는 두 개의 별도 쿼리보다 빠르거나 같은 시간이 걸립니까? – user1697111