टेस्ट केस:
CREATE TABLE tbl (date date, email text);
INSERT INTO tbl VALUES
('2012-01-01', '[email protected]')
, ('2012-01-01', '[email protected]')
, ('2012-01-01', '[email protected]')
, ('2012-01-02', '[email protected]')
, ('2012-01-02', '[email protected]')
, ('2012-01-03', '[email protected]')
, ('2012-01-04', '[email protected]')
, ('2012-01-05', '[email protected]')
, ('2012-01-05', '[email protected]')
, ('2012-01-06', '[email protected]')
, ('2012-01-06', '[email protected]')
, ('2012-01-06', '[email protected]`')
;
प्रश्न - केवल वही दिन लौटाता है जब कोई प्रविष्टि tbl
. में मौजूद होती है :
SELECT date
,(SELECT count(DISTINCT email)
FROM tbl
WHERE date BETWEEN t.date - 2 AND t.date -- period of 3 days
) AS dist_emails
FROM tbl t
WHERE date BETWEEN '2012-01-01' AND '2012-01-06'
GROUP BY 1
ORDER BY 1;
या - वापसी सभी दिन निर्दिष्ट सीमा में, भले ही दिन के लिए कोई पंक्तियाँ न हों:
SELECT date
,(SELECT count(DISTINCT email)
FROM tbl
WHERE date BETWEEN g.date - 2 AND g.date
) AS dist_emails
FROM (SELECT generate_series(timestamp '2012-01-01'
, timestamp '2012-01-06'
, interval '1 day')::date) AS g(date);
db<>फिडल यहाँ
परिणाम:
day | dist_emails
-----------+------------
2012-01-01 | 3
2012-01-02 | 3
2012-01-03 | 3
2012-01-04 | 3
2012-01-05 | 1
2012-01-06 | 2
यह लग रहा था पहली बार विंडो फ़ंक्शंस के लिए नौकरी की तरह, लेकिन मुझे उपयुक्त विंडो फ्रेम को परिभाषित करने का कोई तरीका नहीं मिला। साथ ही, प्रति दस्तावेज़:
<ब्लॉकक्वॉट>
सामान्य समग्र कार्यों के विपरीत, कुल विंडो फ़ंक्शन, DISTINCT
. की अनुमति नहीं देते हैं या ORDER BY
फ़ंक्शन तर्क सूची में उपयोग करने के लिए।
इसलिए मैंने इसे इसके बजाय सहसंबद्ध उपश्रेणियों के साथ हल किया। मुझे लगता है कि यह सबसे चतुर तरीका है।
BTW, "उक्त तिथि और 3 दिन पहले के बीच" 4 . की अवधि होगी दिन। आपकी परिभाषा वहां विरोधाभासी है।
थोड़ा छोटा, लेकिन कुछ दिनों के लिए धीमा:
SELECT g.date, count(DISTINCT email) AS dist_emails
FROM (SELECT generate_series(timestamp '2012-01-01'
, timestamp '2012-01-06'
, interval '1 day')::date) AS g(date)
LEFT JOIN tbl t ON t.date BETWEEN g.date - 2 AND g.date
GROUP BY 1
ORDER BY 1;
संबंधित:
- PostgreSQL में दो तिथियों के बीच समय श्रृंखला उत्पन्न करना
- समय अंतराल के साथ पंक्तियों की रोलिंग गिनती