एक अंतराल और द्वीप वास्तव में समस्या।
मानते हुए:
- "स्ट्रीक्स" अन्य खिलाड़ियों की पंक्तियों से बाधित नहीं होते हैं।
- सभी कॉलम परिभाषित हैं
NOT NULL
. (अन्यथा आपको और अधिक करना होगा।)
यह सबसे सरल और तेज़ होना चाहिए क्योंकि इसके लिए केवल दो तेज़ row_number()
विंडो फ़ंक्शन
:
SELECT DISTINCT ON (player_id)
player_id, count(*) AS seq_len, min(ts) AS time_began
FROM (
SELECT player_id, points, ts
, row_number() OVER (PARTITION BY player_id ORDER BY ts)
- row_number() OVER (PARTITION BY player_id, points ORDER BY ts) AS grp
FROM tbl
) sub
WHERE points = 100
GROUP BY player_id, grp -- omit "points" after WHERE points = 100
ORDER BY player_id, seq_len DESC, time_began DESC;
db<>fiddle यहां
कॉलम नाम का उपयोग करना ts
time
. के बजाय , जो एक आरक्षित शब्द
है मानक एसक्यूएल में। Postgres में इसकी अनुमति है, लेकिन सीमाओं के साथ और इसे पहचानकर्ता के रूप में उपयोग करना अभी भी एक बुरा विचार है।
"ट्रिक" पंक्ति संख्याओं को घटाना है ताकि लगातार पंक्तियाँ एक ही समूह में आएँ (grp
) प्रति (player_id, points)
. फिर 100 अंकों के साथ फ़िल्टर करें, प्रति समूह कुल मिलाकर प्रति खिलाड़ी केवल सबसे लंबा, सबसे हाल का परिणाम लौटाएं।
तकनीक के लिए बुनियादी स्पष्टीकरण:
हम GROUP BY
. का उपयोग कर सकते हैं और DISTINCT ON
उसी में SELECT
, GROUP BY
पहले . लागू किया जाता है DISTINCT ON
. SELECT
. में इवेंट के क्रम पर विचार करें क्वेरी:
DISTINCT ON
. के बारे में :