क्योंकि आप उस आइटम का चयन नहीं कर रहे हैं जिसके द्वारा आप समूह बना रहे हैं। अगर आपने कहा:
GROUP BY c.printable_name
आपको अपेक्षित NULL मिलेगा। हालाँकि आप एक अलग कॉलम द्वारा समूहित कर रहे हैं, इसलिए MySQL को यह नहीं पता है कि प्रिंट करने योग्य_नाम रोलअप-ग्रुप में भाग ले रहा है, और उस कॉलम से किसी भी पुराने मान का चयन करता है, all के जॉइन में पंजीकरण। (तो यह संभव है कि आप उज्बेकिस्तान के अलावा अन्य देशों को देखेंगे।)
यह MySQL के साथ एक व्यापक समस्या का हिस्सा है, जिसे आप GROUP BY क्वेरी में चुन सकते हैं। उदाहरण के लिए, आप कह सकते हैं:
SELECT gender FROM registrations GROUP BY country;
और MySQL खुशी-खुशी प्रत्येक देश से पंजीकरण के लिए लिंग मूल्यों में से एक को चुन लेगा, भले ही देश और लिंग के बीच कोई सीधा कारण लिंक (उर्फ "कार्यात्मक निर्भरता") न हो। अन्य DBMS उपरोक्त आदेश को इस आधार पर अस्वीकार कर देंगे कि प्रति देश एक लिंग होने की गारंटी नहीं है।(*)
अब, यह:
SELECT c.printable_name AS 'Country', count(*) AS '#'
FROM registrations r
INNER JOIN country c ON r.country = c.country_id
GROUP BY country
ठीक है, क्योंकि r.country और c.printable_name के बीच एक कार्यात्मक निर्भरता है (यह मानते हुए कि आपने अपने देश_आईडी को प्राथमिक कुंजी के रूप में सही ढंग से वर्णित किया है)।
हालाँकि MySQL का रोलअप एक्सटेंशन के साथ यह काम करने के तरीके में थोड़ा हैक है। अंत में रोलअप पंक्ति चरण पर, यह अपने मानों को हथियाने के लिए सेट किए गए संपूर्ण प्री-ग्रुपिंग परिणाम पर चलता है, और फिर समूह-दर कॉलम को NULL पर सेट करता है। यह उन अन्य स्तंभों को भी खाली नहीं करता है जिनकी उस स्तंभ पर कार्यात्मक निर्भरता है। यह शायद होना चाहिए, लेकिन MySQL वर्तमान में कार्यात्मक निर्भरता के बारे में पूरी बात को वास्तव में नहीं समझता है।
इसलिए यदि आप c.printable_name का चयन करते हैं, तो यह आपको यादृच्छिक रूप से चुने गए देश के नाम का मान दिखाएगा, और यदि आप c.country_id का चयन करते हैं, तो यह आपको वह देश आईडी दिखाएगा, जिसे उसने यादृच्छिक रूप से चुना था — भले ही c.country_id शामिल होने का मानदंड है, इसलिए यह होना चाहिए r.country के समान, जो NULL है!
समस्या को हल करने के लिए आप क्या कर सकते हैं:
- इसके बजाय Printable_name द्वारा समूहित करें; ठीक होना चाहिए अगर Printable_names अद्वितीय हैं, या
- “r.country” के साथ-साथ Printable_name का चयन करें, और जाँचें कि NULL होने के लिए, या
- रोलअप के साथ भूल जाएं और अंतिम राशि के लिए एक अलग क्वेरी करें। यह थोड़ा धीमा होगा लेकिन यह ANSI SQL-92 के अनुरूप भी होगा ताकि आपका ऐप अन्य डेटाबेस पर काम कर सके।
(*:MySQL में एक SQL_MODE विकल्प है ONLY_FULL_GROUP_BY यह इस मुद्दे को संबोधित करने वाला है, लेकिन यह बहुत दूर जाता है और केवल आपको ग्रुप बाय से कॉलम चुनने देता है, न कि कॉलम जो ग्रुप बाय पर कार्यात्मक निर्भरता रखते हैं। तो यह वैध प्रश्नों को भी विफल कर देगा, जिससे यह आम तौर पर बेकार हो जाएगा।)