2012-11-13 2 views
3

나는 주어진 컴퓨터의 오늘 평균 연결 수를 7 일에서 14 일 사이의 평균 연결 수와 비교하는 쿼리를 작성하려고합니다. 이 윈도우 함수에 의해 처리하는 것이 가장 좋은 것으로 생각하지만 날짜에 대한 올바른 구문을 가져올 수 없습니다.PostgreSQL의 윈도우 함수 후행

필자는 soucreip, destinationip, timestamp를 열로하여 iptable이라는 IP 주소와 연결 레코드 테이블을 가지고 있다고 가정합니다. 이러한 유형의 쿼리 감각을 윈도우 함수 접근법 만드는가를 작성하는 가장 좋은 방법은 또는 거기에 무엇

select 
    sourceip, 
    destinationip, 
    timestamp, 
    count(*) OVER (PARTITION BY sourceip order by timestamp 
       RANGE BETWEEN now() - '7 day'::Interval PRECEDING 
           now() - '14 day'::Interval FOLLOWING) 
from 
iptable; 

: 여기 단지의 SourceIP 당 수를 얻기 위해 7 일 기간을 위해 노력하고 쿼리입니다 큰 테이블의 경우를 위해 일을 더 최적화 된 방법?

+1

모든 질문에 PostgreSQL 버전과 오류 메시지의 정확한 텍스트를 보여주십시오. –

답변

6

끔찍한 열 이름 인 "timestamp"을 선택하셨습니다. timestamp은 내장 데이터 유형의 이름이므로 열 이름으로 사용하려면 "double quote"을 사방에 입력해야합니다.

하지만 그게 전부는 아닙니다. 창 함수 구문이 잘못되었습니다. window function syntax을 참조하십시오. 너는 AND을 잊었다; RANGE BETWEEN .. PRECEDING AND ... FOLLOWING입니다.

또한 문제의 원인이 아니지만 now() 대신 SQL 표준 current_timestamp을 사용해야합니다.

즉, 새로운 오류로 얻을 것이다 : 현재 창 기능 구현이 당신이하고 싶은 일을하지 않을 것을 제안

CREATE TABLE iptable (sourceip cidr, destinationip cidr, "timestamp" timestamptz); 

regress=> select 
    sourceip, 
    destinationip, 
    timestamp, 
    count(*) OVER (PARTITION BY sourceip order by "timestamp" RANGE BETWEEN current_timestamp - '7 day'::Interval PRECEDING AND current_timestamp - '14 day'::Interval FOLLOWING) 

from 
iptable; 
ERROR: RANGE PRECEDING is only supported with UNBOUNDED 
LINE 5: ... OVER (PARTITION BY sourceip order by "timestamp" RANGE BETW... 
                  ^

합니다. 슬프게도.

The value PRECEDING and value FOLLOWING cases are currently only allowed in ROWS mode. They indicate that the frame starts or ends with the row that many rows before or after the current row. value must be an integer expression not containing any variables, aggregate functions, or window functions.

대신에 그냥 입력 행에 WHERE 필터를 사용하여 일반 GROUP BY을 사용하십시오.

select 
    sourceip, 
    count(sourceip) AS n_conns_7_to_14_days_ago 
from 
iptable 
WHERE age("timestamp") BETWEEN INTERVAL '7' DAY AND INTERVAL '14' DAY 
GROUP BY sourceip; 
4

얻으려면 ...

the number of average connections between 7 and 14 days ago

SELECT sourceip, destinationip, timestamp, count(*) AS ct 
FROM iptable 
WHERE "timestamp" BETWEEN now() - '14 day'::interval 
        AND  now() - '7 day'::interval 
GROUP BY 1,2,3; 

그냥 일반 집계 함수를 사용합니다.
그리고 열 이름으로 timestamp을 사용하지 마십시오. 그것은 SQL 표준에 protected word이고 부분적으로는 PostgreSQL을 예약했습니다.