Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

MySQL में GROUP BY को ठीक से कैसे करें?

स्पष्ट करने वाली पहली बात यह है कि SQL MySQL नहीं है।

मानक एसक्यूएल में इसे गैर-एकत्रित क्षेत्रों के सबसेट द्वारा समूहित करने की अनुमति नहीं है। कारण बहुत सरल है। मान लीजिए मैं यह क्वेरी चला रहा हूं:

SELECT color, owner_name, COUNT(*) FROM cars
GROUP BY color

उस क्वेरी का कोई मतलब नहीं होगा। समझाने की कोशिश करना भी असंभव होगा। निश्चित रूप से यह रंगों का चयन कर रहा है और प्रति रंग कारों की मात्रा गिन रहा है। हालांकि, यह owner_name . भी जोड़ रहा है फ़ील्ड और किसी दिए गए रंग के लिए कई स्वामी हो सकते हैं, क्योंकि यह White . का मामला है रंग। तो अगर कई owner_name हो सकते हैं एक color . के लिए मान जो GROUP BY . में एकमात्र फ़ील्ड होता है खंड... तो कौन सा owner_name वापस कर दिया जाएगा?

यदि किसी owner_name को वापस करने की आवश्यकता हो तो तो उनमें से केवल एक का चयन करने के लिए कुछ प्रकार के मानदंड जोड़े जाने चाहिए, उदाहरण के लिए, वर्णानुक्रम में पहला, जो इस मामले में John होगा . उस मानदंड के परिणामस्वरूप एक समग्र कार्य जोड़ा जाएगा MIN(owner_name) और फिर क्वेरी फिर से समझ में आएगी क्योंकि यह चयन कथन में कम से कम, सभी गैर-एकत्रित फ़ील्ड द्वारा समूहीकृत होगी।

जैसा कि आप देख सकते हैं, समूह में मानक SQL के अनम्य होने का एक स्पष्ट और व्यावहारिक कारण है। यदि ऐसा नहीं होता, तो आपको अजीब परिस्थितियों का सामना करना पड़ सकता है जिसमें कॉलम के लिए मूल्य अप्रत्याशित होगा, और यह एक अच्छा शब्द नहीं है, खासकर यदि क्वेरी चल रही है तो आपको अपना बैंक खाता लेनदेन दिखा रहा है।

ऐसा कहने के बाद, MySQL उन प्रश्नों की अनुमति क्यों देगा जिनका कोई मतलब नहीं है? और इससे भी बदतर, उपरोक्त क्वेरी में त्रुटि को केवल वाक्यात्मक रूप से पता लगाया जा सकता है! संक्षिप्त उत्तर है:प्रदर्शन। लंबा उत्तर यह है कि कुछ ऐसी स्थितियां हैं जिनमें डेटा संबंधों के आधार पर, समूह से अप्रत्याशित मूल्य प्राप्त करने से अनुमानित मूल्य प्राप्त होगा।

यदि आपने अभी तक इसका पता नहीं लगाया है, तो समूह से अप्रत्याशित तत्व लेने से आपको प्राप्त होने वाले मूल्य का अनुमान लगाने का एकमात्र तरीका यह होगा कि समूह के सभी तत्व समान हों। इस स्थिति का एक स्पष्ट उदाहरण आपके उसी प्रश्न में नमूना क्वेरी में है। देखें कैसे owner_id और owner_name तालिका में संबंधित है। यह स्पष्ट है कि कोई भी owner_id दिया गया है , जैसे 2 , आपके पास केवल एक अलग owner_name हो सकता है . कई पंक्तियाँ होने पर भी, किसी एक को चुनकर आपको Mike मिलेगा जैसा कि परिणाम है। औपचारिक डेटाबेस शब्दजाल में इसे owner_id . के रूप में समझाया जा सकता है कार्यात्मक रूप से owner_name निर्धारित करता है

आइए पूरी तरह से काम कर रही MySQL क्वेरी पर करीब से नज़र डालें:

SELECT owner_id, owner_name, COUNT(*) total FROM cars
GROUP BY owner_id

किसी भी owner_id को देखते हुए यह वही owner_name लौटाएगा , इसलिए इसे GROUP BY . में जोड़ें क्लॉज के परिणामस्वरूप अधिक पंक्तियाँ वापस नहीं आएंगी। यहां तक ​​कि एक समेकित फ़ंक्शन जोड़ना MAX(owner_name) कम पंक्तियों में परिणाम नहीं होगा। परिणामी डेटा बिल्कुल वही होगा। दोनों ही मामलों में, क्वेरी को तुरंत कानूनी मानक SQL क्वेरी में बदल दिया जाएगा क्योंकि कम से कम सभी गैर-एकत्रित फ़ील्ड को समूहीकृत किया जाएगा। इसलिए समान परिणाम प्राप्त करने के लिए 3 तरीके हैं।

हालांकि, जैसा कि मैंने पहले उल्लेख किया है, इस गैर-मानक समूह का प्रदर्शन लाभ है। आप इस इतने कम रेटिंग वाले लिंक को देख सकते हैं जिसमें इसे और अधिक विस्तार से समझाया गया है लेकिन मैं सबसे महत्वपूर्ण हिस्सा उद्धृत करने जा रहा हूं:

एक बात जो ध्यान देने योग्य है वह यह है कि जरूरी नहीं कि परिणाम गलत हों बल्कि अनिश्चित . दूसरे शब्दों में, अपेक्षित परिणाम प्राप्त करने का अर्थ यह नहीं है कि आपने सही प्रश्न लिखा है। सही क्वेरी लिखने से आपको हमेशा अपेक्षित परिणाम मिलेंगे।

जैसा कि आप देख सकते हैं, यह MySQL एक्सटेंशन को GROUP BY . पर लागू करने लायक हो सकता है खंड। वैसे भी, यदि यह अभी तक 100% स्पष्ट नहीं है, तो एक नियम है जो यह सुनिश्चित करेगा कि आपका समूह हमेशा सही रहेगा:/मजबूत> . हो सकता है कि कुछ स्थितियों में आप कुछ CPU चक्र बर्बाद कर रहे हों लेकिन यह अनिश्चित लौटने से बेहतर है परिणाम। यदि आप अभी भी सही ढंग से समूह न करने से डरते हैं तो ONLY_FULL_GROUP_BY SQL मोड अंतिम उपाय हो सकता है :)

हो सकता है कि आपका समूहन सही और प्रदर्शनकारी हो... या कम से कम सही हो।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. एक सरणी के कम से कम एक तत्व वाले परिणाम प्राप्त करने के लिए Laravel क्वेरी?

  2. एक तालिका से पंक्तियों का चयन करें, एक-से-अनेक संबंध के साथ अन्य तालिका से नवीनतम पंक्ति में शामिल हों

  3. './mysql/user.MYD' नहीं मिला (त्रुटि:2 - ऐसी कोई फ़ाइल या निर्देशिका नहीं)

  4. मैं MySQL में प्राथमिक कुंजी कॉलम का नाम कैसे बदलूं?

  5. सर्वर से Mysql कनेक्ट:उपयोगकर्ता के लिए एक्सेस अस्वीकृत [ईमेल संरक्षित]