गतिविधि के साथ केवल मिनट लौटाएं
सबसे छोटा
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;