इस टेबल पर निर्माण (SQL कीवर्ड "date"का उपयोग नहीं करना ए> कॉलम नाम के रूप में।):
CREATE TABLE tbl(
pid int
, the_date date
, PRIMARY KEY (pid, the_date)
);
प्रश्न:
SELECT pid, the_date
, row_number() OVER (PARTITION BY pid, grp ORDER BY the_date) AS in_streak
FROM (
SELECT *
, the_date - '2000-01-01'::date
- row_number() OVER (PARTITION BY pid ORDER BY the_date) AS grp
FROM tbl
) sub
ORDER BY pid, the_date;
date
घटाना किसी अन्य date
. से एक integer
उत्पन्न करता है . चूंकि आप लगातार दिनों की तलाश में हैं, इसलिए प्रत्येक अगली पंक्ति एक . से बड़ी होगी . अगर हम row_number()
subtract घटाते हैं उस से, पूरी स्ट्रीक एक ही समूह में समाप्त हो जाती है (grp
) प्रति pid
. फिर प्रति समूह संख्या निकालना आसान है।
grp
की गणना दो घटावों के साथ की जाती है, जो सबसे तेज होनी चाहिए। एक समान तेज़ विकल्प हो सकता है:
the_date - row_number() OVER (PARTITION BY pid ORDER BY the_date) * interval '1d' AS grp
एक गुणा, एक घटाव। स्ट्रिंग संयोजन और कास्टिंग अधिक महंगा है। EXPLAIN ANALYZE
. के साथ परीक्षण करें ।
pid
. द्वारा विभाजन करना न भूलें इसके अतिरिक्त दोनों . में कदम, या आप अनजाने में उन समूहों को मिला देंगे जिन्हें अलग किया जाना चाहिए।
सबक्वेरी का उपयोग करना, क्योंकि यह आमतौर पर CTE से तेज होता है। . यहाँ ऐसा कुछ भी नहीं है जो एक सादा सबक्वेरी नहीं कर सकता।
और चूंकि आपने इसका उल्लेख किया है:dense_rank()
स्पष्ट रूप से नहीं है यहाँ आवश्यक है। बेसिक row_number()
काम करता है।