PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

रोलिंग दिनांक सीमा में अलग-अलग मानों की गणना के लिए क्वेरी

टेस्ट केस:

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 में दो तिथियों के बीच समय श्रृंखला उत्पन्न करना
  • समय अंतराल के साथ पंक्तियों की रोलिंग गिनती


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL डेटाबेस का ऑडिट कैसे करें

  2. पोस्टग्रेस्क्ल ड्रॉप व्यू

  3. पोस्टग्रेज:मानों के योग का चयन करें और फिर इसे फिर से जोड़ दें

  4. VMware क्लाउड इंफ्रास्ट्रक्चर पर स्केलग्रिड पोस्टग्रेएसक्यूएल

  5. पूरे डेटाबेस में खाली स्ट्रिंग्स ('') को NULL पर सेट करें