PostgreSQL में प्रत्येक समूह की नवीनतम पंक्ति: row_number ऑर्डरिंग को निर्धारित बनाएं
प्रत्येक खाते के लिए एक पूर्ण घटना का चयन करें एक स्पष्ट टाई-ब्रेकर और लापता टाइमस्टैम्प के लिए एक जानबूझकर नीति के साथ।
इस पृष्ठ पर
संक्षिप्त उत्तर
प्रत्येक समूह को इसके पहचानकर्ता के आधार पर PARTITION BY के साथ row_number का उपयोग करके रैंक करें और इवेंट टाइमस्टैम्प के साथ एक स्थिर विशिष्ट टाई-ब्रेकर को ORDER BY में जोड़ें। फिर एक बाहरी क्वेरी में rn=1 को फ़िल्टर करें। यदि लापता टाइमस्टैम्प को ज्ञात टाइमस्टैम्प से पीछे रखना है तो NULLS LAST का उपयोग करें। विंडो ऑर्डरिंग समूह के भीतर विजेता का चयन करती है; चयनित पंक्तियों को प्रदर्शित करने के क्रम को एक अलग बाहरी ORDER BY नियंत्रित करता है।
छोटे क्वेरी उदाहरण का अनुसरण करें
निर्मित खाता 7 में घटनाएं 10 और 11 एक ही टाइमस्टैम्प के साथ हैं, इसलिए id DESC 11 का चयन करता है। खाता 8 में केवल घटना 12 है, इसलिए यह 12 का चयन करता है भले ही इसका टाइमस्टैम्प लापता हो। NULLS LAST लापता मानों को हटाता नहीं है; यह प्रत्येक समूह के भीतर ज्ञात मानों के पीछे उन्हें रखता है। ये क्वेरी के अपेक्षित परिणाम हैं, इस परियोजना के विरुद्ध निष्पादित किसी क्वेरी का आउटपुट नहीं।
पूर्ण विजेता पंक्ति को संरक्षित करें
max(event_time) जैसा एक समूहक एक टाइमस्टैम्प खोजता है लेकिन स्वयं उस पंक्ति से अन्य स्तंभों का चयन नहीं करता जिसका वह संबंधित है। उस अधिकतम को तालिका के साथ वापस जोड़ने से कई पंक्तियां लौट सकती हैं जब टाइमस्टैम्प टाई होते हैं। विंडो रैंकिंग इसके विपरीत प्रत्येक उम्मीदवार को एक स्थिति प्रदान करती है जबकि उसका पेलोड और पहचानकर्ता बनाए रखती है। आपको अभी भी एक स्पष्ट नीति की आवश्यकता है यदि व्यवसाय सभी टाई वाली नवीनतम घटनाओं को चाहता है न कि केवल एक।
विभाजन और क्रम व्यवस्था को स्वतंत्र रूप से करें
PARTITION BY account_id प्रत्येक खाते के लिए एक अलग रैंकिंग बनाता है। विंडो ORDER BY event_time DESC NULLS LAST, id DESC ज्ञात नवीनतम टाइमस्टैम्प को पहले रखता है और पहचानकर्ता का उपयोग करके समान टाइमस्टैम्प को तोड़ता है। उस क्रम के निर्धारित होने के लिए पहचानकर्ता को उस क्रम की उम्मीदवार पंक्तियों के बीच भेद करना आवश्यक है। यदि स्रोत ऐसी कोई कुंजी प्रदान नहीं करता है तो भौतिक पंक्ति भंडारण क्रम पर निर्भर करने के बजाय कोई अन्य स्थिर विशिष्ट टाई-ब्रेकर चुनें।
नवीनतम का अर्थ परिभाषित करें
चयन के लिए उपयोग किए जाने वाले इवेंट टाइमस्टैम्प और यह कि क्या लापता मान योग्य हैं, को निर्दिष्ट करें। अंतर्ग्रहण समय, व्यावसायिक इवेंट समय और एक संख्यात्मक पहचानकर्ता नवीनता के विभिन्न विचारों का प्रतिनिधित्व कर सकते हैं। एक उच्च पहचानकर्ता इस उदाहरण में एक सुविधाजनक निर्धारित टाई-ब्रेकर है, यह प्रमाण नहीं कि कोई घटना बाद में हुई थी। उस नियम पर लिखने से पहले सहमत हों, विशेष रूप से जब घटनाएं गलत क्रम में आ सकती हैं।
WITH events (id, account_id, event_time, payload) AS (
VALUES
(10, 7, TIMESTAMP '2026-09-30 10:00:00', 'first'),
(11, 7, TIMESTAMP '2026-09-30 10:00:00', 'second'),
(12, 8, NULL::timestamp, 'unknown time')
), ranked AS (
SELECT events.*,
row_number() OVER (
PARTITION BY account_id
ORDER BY event_time DESC NULLS LAST, id DESC
) AS rn
FROM events
)
SELECT id, account_id, event_time, payload
FROM ranked
WHERE rn = 1
ORDER BY account_id;
सही क्वेरी परत में फ़िल्टर करें
विंडो परिणाम उस क्वेरी परत द्वारा चयनित इनपुट पंक्तियों के बाद गणना की जाती है। CTE एक परत प्रदान करता है जहाँ rn एक स्तंभ के रूप में मौजूद होता है, और बाहरी क्वेरी उसे फ़िल्टर करती है। रैंकिंग से पहले उम्मीदवारों को फ़िल्टर करना और बाद में चयनित विजेताओं को फ़िल्टर करना भी अलग-अलग है। उदाहरण के लिए, नवीनतम सफल घटना और नवीनतम घटना जो संयोग से सफल है, अलग-अलग प्रश्नों के उत्तर देते हैं और आउटपुट में अलग-अलग खाते उत्पन्न कर सकते हैं।
अनुपस्थित समूह पहचानकर्ताओं के लिए नीति तय करें
यदि account_id शून्य हो सकता है, तो वे पंक्तियाँ स्वचालित रूप से अलग खाते बनने के बजाय एक साथ एक खंड बनाती हैं। निर्णय लें कि क्या रैंकिंग से पहले उन्हें हटाना है या उन्हें स्पष्ट रूप से परिभाषित एक समूह के रूप में मानना है। इसी तरह, NULLS LAST एक सभी-शून्य टाइमस्टैम्प खंड से विजेता उत्पन्न करने की अनुमति देता है। यदि अज्ञात टाइमस्टैम्प को कभी भी चुना नहीं जाना चाहिए, तो उन्हें क्रम वाक्य के द्वारा हटाए जाने की अपेक्षा करने के बजाय उम्मीदवार इनपुट से हटा दें।
आउटपुट क्रम और समवर्ती परिवर्तनों की जाँच करें
बाहरी ORDER BY account_id एक प्रदर्शन क्रम देता है; यह यह तय नहीं करता कि कौन सा घटना जीती। बाहरी क्रम वाक्य के बिना, अनुप्रयोगों को यह मानना नहीं चाहिए कि पंक्तियाँ स्थिर प्रस्तुति क्रम में आती हैं। क्वेरी अपने स्नैपशॉट को पढ़ने के बाद डाली गई नई घटनाएँ बाद के क्वेरी परिणाम को बदल सकती हैं। निर्णायक टाई-टूटना विचार की गई पंक्तियों के लिए चयन को स्पष्ट बनाता है, लेकिन अलग-अलग क्वेरियों पर बदलते डेटासेट को स्थिर नहीं करता।
वास्तविक कार्यभार पर प्रदर्शन की जाँच करें
किसी अनुक्रमण को चुनने से पहले वास्तविक समूह आकारों और चयनित स्तंभों के साथ क्वेरी योजना का मूल्यांकन करें। खंड और क्रम वाक्य स्तंभों वाला अनुक्रमण कुछ कार्यभार में सहायक हो सकता है, लेकिन यह सार्वभौमिक वादा नहीं है कि क्रमबद्ध करना गायब हो जाएगा या हर पेलोड कवर किया जाएगा। सबसे पहले सही चयन अर्थशास्त्र को बनाए रखें। यदि PostgreSQL की किसी अन्य तकनीक जैसे DISTINCT ON चुना जाता है, तो परिणामों की तुलना करते समय वही शून्य और टाई नियम बनाए रखें।
क्या जाँचें
- टाइमस्टैम्प और नल नीति को परिभाषित करें।
- एक स्थिर विशिष्ट टाई-ब्रेकर का उपयोग करें।
- विंडो परिणामों को एक बाहरी परत में फ़िल्टर करें।
- उम्मीदवार फ़िल्टर को विजेता फ़िल्टर से अलग रखें।
- प्रस्तुति के लिए बाहरी ORDER BY का उपयोग करें।
उपयोग की सीमाएँ
यह क्वेरी बताई गई ऑर्डरिंग के अंतर्गत प्रत्येक विभाजन से एक विजेता का चयन करती है। यह सभी टाई नहीं लौटाती, पहचानकर्ताओं से इवेंट टाइम अनुमानित नहीं करती, सभी-नल समूहों को स्वचालित रूप से बाहर नहीं करती और किसी इंडेक्स योजना की गारंटी नहीं देती। उदाहरण पंक्तियां काल्पनिक हैं।