首頁 >資料庫 >mysql教程 >如何在 PostgreSQL 中有效率地統計某個時間範圍內的前行數?

如何在 PostgreSQL 中有效率地統計某個時間範圍內的前行數?

Linda Hamilton
Linda Hamilton原創
2024-12-27 07:27:12416瀏覽

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
);

表:

表:
SELECT id, ts
     , count(*) OVER (ORDER BY ts RANGE '1 hour' PRECEDING EXCLUDE CURRENT ROW)
FROM   test
ORDER  BY ts;

圖片高版本:

Postgres 11 引入了改進的視窗函數框架選項,允許使用 RANGE使用 PRECEDING 和 FOLLOWING 的模式來選擇指定偏移量內的行。

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;

Postgres 10 或更早版本:

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;
ROM(Roman 的查詢):

ROM(Roman 的查詢):

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$;

ARR (計算數組元素):

SELECT * FROM running_window_ct();

COR(相關子查詢):

調用函數:基準結果:使用具有不同行數的表進行的基準測試表明,FNC 函數在性能和可擴展性方面明顯勝出。

以上是如何在 PostgreSQL 中有效率地統計某個時間範圍內的前行數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn