> 데이터 베이스 > MySQL 튜토리얼 > PostgreSQL에서 시간 범위 내에서 이전 행을 효율적으로 계산하는 방법은 무엇입니까?

PostgreSQL에서 시간 범위 내에서 이전 행을 효율적으로 계산하는 방법은 무엇입니까?

Linda Hamilton
풀어 주다: 2024-12-27 07:27:12
원래의
453명이 탐색했습니다.

How to Efficiently Count Preceding Rows Within a Time Range in PostgreSQL?

범위 내의 이전 행 계산

문제 설명:

정의된 시간 내에 이전 레코드의 총 개수 결정 테이블의 각 행에 대한 범위.

특정 시나리오:

쿼리:

SELECT id, date
     , count(*) OVER (HAVING previous_rows.date >= (date - '1 hour'::interval))  -- ?
FROM test;
로그인 후 복사

테이블:

CREATE TABLE test (
  id  bigint
, ts  timestamp
);
로그인 후 복사

Postgres 11 이상:

Postgres 11에는 향상된 창 기능 프레이밍 옵션이 도입되어 RANGE를 사용할 수 있습니다. PRECEDING 및 FOLLOWING을 사용하여 지정된 오프셋 내의 행을 선택합니다.

SELECT id, ts
     , count(*) OVER (ORDER BY ts RANGE '1 hour' PRECEDING EXCLUDE CURRENT ROW)
FROM   test
ORDER  BY ts;
로그인 후 복사

Postgres 10 이하:

ROM(Roman의 쿼리):

SELECT id, ts
     , (SELECT count(*)::int - 1
        FROM   unnest(dates) x
        WHERE  x >= sub.ts - interval '1h') AS ct
FROM (
   SELECT id, ts
        , array_agg(ts) OVER(ORDER BY ts) AS dates
   FROM   test
   ) sub;
로그인 후 복사

ARR (배열 요소 개수):

SELECT id, ts
     , (SELECT count(*)
        FROM   test t1
        WHERE  t1.ts >= t.ts - interval '1h'
        AND    t1.ts < t.ts) AS ct
FROM   test t
ORDER  BY ts;
로그인 후 복사

COR(상관 하위 쿼리):

CREATE OR REPLACE FUNCTION running_window_ct(_intv interval = '1 hour')
  RETURNS TABLE (id bigint, ts timestamp, ct int)
  LANGUAGE plpgsql AS
$func$
DECLARE
   cur   CURSOR FOR
         SELECT t.ts + _intv AS ts1
              , row_number() OVER (ORDER BY t.ts ROWS UNBOUNDED PRECEDING) AS rn
         FROM   test t
         ORDER  BY t.ts;
   rec   record;
   rn    int;
BEGIN
   OPEN cur;
   FETCH cur INTO rec;
   ct := -1;  -- init

   FOR id, ts, rn IN
      SELECT t.id, t.ts
           , row_number() OVER (ORDER BY t.ts ROWS UNBOUNDED PRECEDING)
      FROM   test t ORDER BY t.ts
   LOOP
      IF rec.ts1 >= ts THEN
         ct := ct + 1;
      ELSE
         LOOP
            FETCH cur INTO rec;
            EXIT WHEN rec.ts1 >= ts;
         END LOOP;
         ct := rn - rec.rn;
      END IF;

      RETURN NEXT;
   END LOOP;
END
$func$;
로그인 후 복사

함수 호출:

SELECT * FROM running_window_ct();
로그인 후 복사

벤치마크 결과:

행 개수가 다양한 테이블을 사용한 벤치마크 결과 FNC 기능이 성능과 확장성 측면에서 확실한 승리를 거두었습니다.

위 내용은 PostgreSQL에서 시간 범위 내에서 이전 행을 효율적으로 계산하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿