समस्या:
आपने अपने डेटा को GROUP BY
. के साथ समूहीकृत किया है और प्रत्येक समूह से केवल पहली पंक्ति प्रदर्शित करना चाहते हैं।
उदाहरण:
हमारे डेटाबेस में exam_results
निम्न तालिका में डेटा के साथ:
last_name | वर्ष | <थ>परिणाम||
---|---|---|---|
जॉन | क्लेन | 2020 | 40 |
एडिथ | काला | 2020 | 43 |
चिह्नित करें | जॉनसन | 2019 | 32 |
लौरा | गर्मी | 2020 | 35 |
केट | स्मिथ | 2019 | 41 |
जैकब | काला | 2019 | 44 |
टॉम | बेनेट | 2020 | 38 |
एमिली | केली | 2020 | 43 |
आइए प्रत्येक वर्ष के लिए सर्वोत्तम result
वाले छात्र को खोजें . अगर किसी समूह में दो छात्र सर्वश्रेष्ठ के लिए बंधे हैं, तो हम मनमाने ढंग से उनमें से एक को प्रदर्शित करने के लिए चुनेंगे।
समाधान:
WITH added_row_number AS ( SELECT *, ROW_NUMBER() OVER(PARTITION BY year ORDER BY result DESC) AS row_number FROM exam_results ) SELECT * FROM added_row_number WHERE row_number = 1;
नतीजा यह है:
last_name | वर्ष | <थ>परिणामपंक्ति_संख्या | ||
---|---|---|---|---|
जैकब | काला | 2019 | 44 | 1 |
एमिली | केली | 2020 | 43 | 1 |
चर्चा:
सबसे पहले, आपको एक सीटीई लिखना होगा जिसमें आप प्रत्येक समूह के भीतर प्रत्येक पंक्ति को एक संख्या निर्दिष्ट करते हैं। ऐसा करने के लिए, आप ROW_NUMBER()
. का उपयोग कर सकते हैं समारोह। OVER()
. में , आप उन समूहों को निर्दिष्ट करते हैं जिनमें पंक्तियों को विभाजित किया जाना चाहिए (PARTITION BY
) और वह क्रम जिसमें पंक्तियों को संख्याएँ सौंपी जानी चाहिए (ORDER BY
)।
आंतरिक क्वेरी के परिणाम पर एक नज़र डालें:
SELECT *, ROW_NUMBER() OVER(PARTITION BY year ORDER BY result DESC) AS row_number FROM exam_results;
last_name | वर्ष | <थ>परिणामपंक्ति_संख्या | ||
---|---|---|---|---|
जैकब | काला | 2019 | 44 | 1 |
केट | स्मिथ | 2019 | 41 | 2 |
चिह्नित करें | जॉनसन | 2019 | 32 | 3 |
एमिली | केली | 2020 | 43 | 1 |
एडिथ | काला | 2020 | 43 | 2 |
जॉन | क्लेन | 2020 | 40 | 3 |
टॉम | बेनेट | 2020 | 38 | 4 |
लौरा | गर्मी | 2020 | 35 | 5 |
आप प्रत्येक समूह (अर्थात, वर्ष) के भीतर पंक्ति संख्याएँ निर्दिष्ट करते हैं। प्रत्येक पंक्ति में result
. के मान के आधार पर एक पंक्ति संख्या होती है कॉलम। DESC
. के कारण पंक्तियों को अवरोही क्रम में क्रमबद्ध किया जाता है ORDER BY result
. के बाद कीवर्ड . भले ही किसी समूह के भीतर कई पंक्तियाँ हों जिनका result
. का एक ही मान हो , पंक्तियों को अभी भी अलग-अलग संख्याएँ दी गई हैं। यहाँ, एडिथ ब्लैक और एमिली केली का result
समान है लेकिन अलग पंक्ति संख्या। इस व्यवहार को बदलने और समूह के भीतर समान परिणाम के लिए समान पंक्ति संख्या निर्दिष्ट करने के लिए, RANK()
का उपयोग करें या DENSE_RANK()
ROW_NUMBER()
. के बजाय ।
बाहरी क्वेरी में, आप सीटीई (added_row_number
) और WHERE
. का उपयोग करें प्रत्येक समूह से प्रदर्शित करने के लिए कौन सी पंक्ति निर्दिष्ट करने के लिए शर्त। यहां, हम पहली पंक्ति प्रदर्शित करना चाहते हैं, इसलिए शर्त है row_number = 1
।
ध्यान दें कि आप समाधान को आसानी से संशोधित कर सकते हैं, उदाहरण के लिए, दूसरी पंक्ति प्रत्येक समूह के।
WITH added_row_number AS ( SELECT *, ROW_NUMBER() OVER(PARTITION BY year ORDER BY result DESC) AS row_number FROM exam_results ) SELECT * FROM added_row_number WHERE row_number = 2;
ये रहा परिणाम:
last_name | वर्ष | <थ>परिणामपंक्ति_संख्या | ||
---|---|---|---|---|
केट | स्मिथ | 2019 | 41 | 2 |
एडिथ | काला | 2020 | 43 | 2 |
दूसरी ओर, यदि आप पंक्ति(पंक्तियों) को दूसरा उच्चतम मान . के साथ प्राप्त करना चाहते हैं result
. का प्रत्येक समूह के भीतर, आपको DENSE_RANK()
. का उपयोग करना चाहिए समारोह। जबकि ROW_NUMBER()
फ़ंक्शन समूह में प्रत्येक पंक्ति के लिए लगातार संख्याएँ बनाता है, जिसके परिणामस्वरूप समान परिणाम वाली पंक्तियों को अलग-अलग मान दिए जाते हैं, DENSE_RANK()
फ़ंक्शन समान परिणाम वाली पंक्तियों को समान संख्या देता है।
WITH added_dense_rank AS ( SELECT *, DENSE_RANK() OVER(PARTITION BY year ORDER BY result DESC) AS rank FROM exam_results ) SELECT * FROM added_dense_rank WHERE rank = 2;
last_name | वर्ष | <थ>परिणाम <थ>रैंक|||
---|---|---|---|---|
केट | स्मिथ | 2019 | 41 | 2 |
जॉन | क्लेन | 2020 | 40 | 2 |
आप देख सकते हैं कि जॉन क्लेन का result (40)
. का दूसरा उच्चतम मान है वर्ष 2020 के लिए। जॉन क्लेन वास्तव में समूह में तीसरे व्यक्ति हैं, लेकिन पहले दो छात्रों का result
समान है। और उन दोनों के पास rank = 1
. है ।