再帰CTE
各行は前の行に依存しているため、セットベースのアプローチで解決するのは困難です。 再帰CTE に頼る (これは標準SQLです):
WITH RECURSIVE cte AS (
(SELECT ts FROM tbl
ORDER BY ts
LIMIT 1)
UNION ALL
(SELECT t.ts
FROM cte c
JOIN tbl t ON t.ts >= c.ts + interval '5 min'
ORDER BY t.ts
LIMIT 1)
)
SELECT * FROM cte ORDER BY ts;
最初のドラフトからの更新に注意してください。
再帰CTEでは集計関数は許可されていません。 ORDER BY
に置き換えました / LIMIT 1
、インデックスでサポートされている場合は高速である必要があります ts
で 。
UNION
の各脚を囲む括弧 LIMIT
を許可するにはクエリが必要です 、それ以外の場合は、UNION
の最後に1回だけ許可されます クエリ。
PL/pgSQL関数
ソートされたテーブルを反復処理する手続き型ソリューション(plpgsql関数を使用した例)は、単一のテーブルスキャンで実行できるため、おそらくはるかに高速です。
CREATE OR REPLACE FUNCTION f_rowgrid(i interval)
RETURNS SETOF timestamp AS
$func$
DECLARE
_this timestamp;
_last timestamp := '-infinity'; -- init so that 1 row passes
BEGIN
FOR _this IN
SELECT ts FROM tbl ORDER BY 1
LOOP
IF _this >= _last + i THEN
RETURN NEXT _this;
_last := _this;
END IF;
END LOOP;
END
$func$ LANGUAGE plpgsql;
電話:
SELECT * FROM f_rowgrid('5 min')
SQLフィドル 両方を示しています。
このタイプのplpgsql関数のやや複雑な例を次に示します。
動的SQLとEXECUTE
を使用して簡単に汎用化できます 任意のテーブルで機能します。