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

PostgreSQL:'मिनट के हिसाब से' क्वेरी के लिए पंक्तियों की गिनती चल रही है

गतिविधि के साथ केवल मिनट लौटाएं

सबसे छोटा

SELECT DISTINCT
       date_trunc('minute', "when") AS minute
     , count(*) OVER (ORDER BY date_trunc('minute', "when")) AS running_ct
FROM   mytable
ORDER  BY 1;

date_trunc() Use का उपयोग करें , यह ठीक वही लौटाता है जिसकी आपको आवश्यकता है।

id शामिल न करें क्वेरी में, चूंकि आप GROUP BY . करना चाहते हैं मिनट स्लाइस।

count() आमतौर पर सादे कुल कार्य के रूप में उपयोग किया जाता है। एक OVER जोड़ना क्लॉज इसे एक विंडो फंक्शन बनाता है। PARTITION BY को छोड़ दें विंडो की परिभाषा में - आप सभी पंक्तियों में की गिनती चलाना चाहते हैं . डिफ़ॉल्ट रूप से, यह ORDER BY द्वारा परिभाषित के अनुसार, पहली पंक्ति से वर्तमान पंक्ति के अंतिम पीयर तक गिना जाता है . मैनुअल:

<ब्लॉकक्वॉट>

डिफ़ॉल्ट फ़्रेमिंग विकल्प RANGE UNBOUNDED PRECEDING . है , जो RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW के समान है . ORDER BY . के साथ , यह फ्रेम को विभाजन से सभी पंक्तियों के रूप में सेट करता है जो वर्तमान पंक्ति के अंतिम ORDER BY से शुरू होता है सहकर्मी।

और ऐसा होता है बिल्कुल आपको क्या चाहिए।

count(*) का उपयोग करें count(id) . के बजाय . यह आपके प्रश्न ("पंक्तियों की गिनती") के लिए बेहतर है। यह आम तौर पर थोड़ा तेज़ होता है count(id) . की तुलना में . और, जबकि हम मान सकते हैं कि id है NOT NULL , यह प्रश्न में निर्दिष्ट नहीं किया गया है, इसलिए count(id) गलत है , कड़ाई से बोलते हुए, क्योंकि NULL मानों की गणना count(id) के साथ नहीं की जाती है ।

आप GROUP BY नहीं कर सकते एक ही क्वेरी स्तर पर मिनट स्लाइस। सकल कार्य पहले . लागू किए जाते हैं विंडो फ़ंक्शन, विंडो फ़ंक्शन count(*) इस तरह प्रति मिनट केवल 1 पंक्ति दिखाई देगी।
हालांकि, आप SELECT DISTINCT कर सकते हैं , क्योंकि DISTINCT बाद . लागू किया जाता है विंडो फ़ंक्शन।

ORDER BY 1 ORDER BY date_trunc('minute', "when") . के लिए बस शॉर्टहैंड है यहाँ।
1 SELECT . में पहली व्यंजक के लिए स्थितीय संदर्भ संदर्भ है सूची।

to_char() Use का उपयोग करें यदि आपको परिणाम को प्रारूपित करने की आवश्यकता है। पसंद:

SELECT DISTINCT
       to_char(date_trunc('minute', "when"), 'DD.MM.YYYY HH24:MI') AS minute
     , count(*) OVER (ORDER BY date_trunc('minute', "when")) AS running_ct
FROM   mytable
ORDER  BY date_trunc('minute', "when");

सबसे तेज़

SELECT minute, sum(minute_ct) OVER (ORDER BY minute) AS running_ct
FROM  (
   SELECT date_trunc('minute', "when") AS minute
        , count(*) AS minute_ct
   FROM   tbl
   GROUP  BY 1
   ) sub
ORDER  BY 1;

बहुत कुछ ऊपर जैसा है, लेकिन:

मैं प्रति मिनट पंक्तियों को एकत्रित करने और गिनने के लिए एक सबक्वायरी का उपयोग करता हूं। इस तरह हमें DISTINCT . के बिना प्रति मिनट 1 पंक्ति मिलती है बाहरी में SELECT

sum() का उपयोग करें सबक्वेरी से गिनती जोड़ने के लिए अब विंडो एग्रीगेट फ़ंक्शन के रूप में।

मैंने इसे प्रति मिनट कई पंक्तियों के साथ काफी तेज पाया।

बिना गतिविधि के मिनट शामिल करें

सबसे छोटा

@GabiMe ने एक टिप्पणी में पूछा कि हर . के लिए एक पंक्ति कैसे प्राप्त करें minute समय सीमा में, जिसमें कोई घटना नहीं हुई (आधार तालिका में कोई पंक्ति नहीं):

SELECT DISTINCT
       minute, count(c.minute) OVER (ORDER BY minute) AS running_ct
FROM  (
   SELECT generate_series(date_trunc('minute', min("when"))
                        ,                      max("when")
                        , interval '1 min')
   FROM   tbl
   ) m(minute)
LEFT   JOIN (SELECT date_trunc('minute', "when") FROM tbl) c(minute) USING (minute)
ORDER  BY 1;

generate_series() के साथ पहली और आखिरी घटना के बीच की समय सीमा में हर मिनट के लिए एक पंक्ति उत्पन्न करें - यहाँ सीधे सबक्वेरी से एकत्रित मूल्यों पर आधारित है।

LEFT JOIN सभी टाइमस्टैम्प को मिनट और गिनने के लिए छोटा कर दिया। NULL मान (जहां कोई पंक्ति मौजूद नहीं है) चल रही गिनती में नहीं जुड़ते हैं।

सबसे तेज़

सीटीई के साथ:

WITH cte AS (
   SELECT date_trunc('minute', "when") AS minute, count(*) AS minute_ct
   FROM   tbl
   GROUP  BY 1
   ) 
SELECT m.minute
     , COALESCE(sum(cte.minute_ct) OVER (ORDER BY m.minute), 0) AS running_ct
FROM  (
   SELECT generate_series(min(minute), max(minute), interval '1 min')
   FROM   cte
   ) m(minute)
LEFT   JOIN cte USING (minute)
ORDER  BY 1;

फिर से, पहले चरण में प्रति मिनट पंक्तियों को एकत्रित और गिनें, यह बाद में DISTINCT की आवश्यकता को छोड़ देता है ।

count() . से अलग , sum() NULL लौटा सकते हैं . 0 . के लिए डिफ़ॉल्ट COALESCE . के साथ ।

कई पंक्तियों और इंडेक्स पर "when" . के साथ पोस्टग्रेज 9.1 - 9.4:

के साथ मेरे द्वारा परीक्षण किए गए कुछ प्रकारों में सबक्वेरी वाला यह संस्करण सबसे तेज़ था
SELECT m.minute
     , COALESCE(sum(c.minute_ct) OVER (ORDER BY m.minute), 0) AS running_ct
FROM  (
   SELECT generate_series(date_trunc('minute', min("when"))
                        ,                      max("when")
                        , interval '1 min')
   FROM   tbl
   ) m(minute)
LEFT   JOIN (
   SELECT date_trunc('minute', "when") AS minute
        , count(*) AS minute_ct
   FROM   tbl
   GROUP  BY 1
   ) c USING (minute)
ORDER  BY 1;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. इनपुट फ़ाइल एक टेक्स्ट प्रारूप डंप प्रतीत होती है। कृपया psql . का उपयोग करें

  2. WHERE क्लॉज में संदर्भ उपनाम

  3. 3 मिलियन पंक्तियों के साथ PostgreSQL डेटाबेस पर धीमी सरल अद्यतन क्वेरी

  4. टाइमज़ोन ऑफ़सेट के साथ दिनांक प्राप्त करना

  5. PostgreSQL में एक यूनिक्स टाइमस्टैम्प को दिनांक/समय मान में कैसे बदलें