पुनरावर्ती 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;
मेरे पहले मसौदे के अपडेट पर ध्यान दें:
पुनरावर्ती सीटीई में कुल कार्यों की अनुमति नहीं है। मैंने ORDER BY
. से प्रतिस्थापित किया / LIMIT 1
, जो किसी अनुक्रमणिका . द्वारा समर्थित होने पर तेज़ होना चाहिए ts
. पर ।
UNION
. के प्रत्येक चरण के चारों ओर कोष्ठक LIMIT
. को अनुमति देने के लिए क्वेरी आवश्यक है , जिसे अन्यथा केवल UNION
. के अंत में केवल एक बार अनुमति दी जाएगी क्वेरी।
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 Fiddle दोनों का प्रदर्शन।
यहाँ इस प्रकार के plpgsql फ़ंक्शन के लिए कुछ अधिक जटिल उदाहरण दिया गया है:
डायनेमिक SQL और EXECUTE
. के साथ आसानी से सामान्य बनाया जा सकता है मनमानी तालिकाओं के लिए काम करने के लिए।