2012-06-05 17 views
5

एक MySQL क्वेरी में, DISTINCT विकल्प का उपयोग करते समय, डुप्लिकेट हटा दिए जाने के बाद ORDER BY लागू होता है? यदि नहीं, तो ऐसा करने का कोई तरीका है? मुझे लगता है कि यह मेरे कोड के साथ कुछ मुद्दों का कारण बन रहा है।DISTINCT से पहले या बाद में आवेदन करने के द्वारा आदेश दिया गया है?

संपादित:
यहाँ मेरी समस्या खड़ी कर रहा है के बारे में कुछ और जानकारी है। मैं समझता हूं कि, पहली नज़र में, यह आदेश महत्वपूर्ण नहीं होगा, क्योंकि मैं डुप्लिकेट पंक्तियों से निपट रहा हूं। हालांकि, यह पूरी तरह से मामला नहीं है, क्योंकि मैं पंक्तियों को क्रमबद्ध करने के लिए INNER JOIN का उपयोग कर रहा हूं। मैं निम्नलिखित MySQL का उपयोग कर रहा

+----+----------+--------+---------+ 
| id | threadid | userid | content | 
+----+----------+--------+---------+ 
| 1 |  1 |  1 | Lorem | 
| 2 |  1 |  2 | Ipsum | 
| 3 |  2 |  2 | Test | 
| 4 |  3 |  1 | Foo  | 
| 5 |  2 |  3 | Bar  | 
| 6 |  3 |  5 | Bob  | 
| 7 |  1 |  2 | Joe  | 
+----+----------+--------+---------+ 

:

+----+--------+-------------+ 
| id | userid | title | 
+----+--------+-------------+ 
| 1 |  1 | Information | 
| 2 |  1 | FAQ   | 
| 3 |  2 | Support  | 
+----+--------+-------------+ 

मैं भी इस तरह एक और तालिका में पदों का एक सेट है:

इस डेटा युक्त मैं मंच धागे की एक मेज है कहो, सभी थ्रेड प्राप्त करने के लिए क्वेरी, फिर उन्हें नवीनतम पोस्ट के आधार पर क्रमबद्ध करें (मान लीजिए कि उच्च आईडी वाले पोस्ट अधिक हालिया हैं:

SELECT t.* 
FROM Threads t 
INNER JOIN Posts p ON t.id = p.threadid 
ORDER BY p.id DESC 

यह काम करता है, और कुछ इस तरह उत्पन्न करता है:

+----+--------+-------------+ 
| id | userid | title | 
+----+--------+-------------+ 
| 1 |  1 | Information | 
| 3 |  2 | Support  | 
| 2 |  1 | FAQ   | 
| 3 |  2 | Support  | 
| 2 |  1 | FAQ   | 
| 1 |  1 | Information | 
| 1 |  1 | Information | 
+----+--------+-------------+ 

लेकिन, जैसा कि आप देख सकते हैं, जानकारी सही है, लेकिन वहाँ डुप्लीकेट पंक्तियों कर रहे हैं। मैं ऐसे डुप्लीकेट को हटाना चाहता हूं, इसलिए मैंने SELECT DISTINCT का उपयोग किया। हालांकि, यह निम्नलिखित उत्पन्न हुआ:

+----+--------+-------------+ 
| id | userid | title | 
+----+--------+-------------+ 
| 3 |  2 | Support  | 
| 2 |  1 | FAQ   | 
| 1 |  1 | Information | 
+----+--------+-------------+ 

यह स्पष्ट रूप से गलत है, क्योंकि "सूचना" धागा शीर्ष पर होना चाहिए। ऐसा लगता है कि DISTINCT का उपयोग करके डुप्लिकेट को ऊपर से नीचे तक हटा दिया जाता है, इसलिए केवल अंतिम पंक्तियां ही छोड़ी जाती हैं। यह सॉर्टिंग में कुछ मुद्दों का कारण बनता है।

क्या यह मामला है, या क्या मैं गलत तरीके से विश्लेषण कर रहा हूं?

+2

आपको क्या लगता है कि यह क्या कारण है? इससे क्या फर्क पड़ता है? – eggyal

+1

इससे कोई फर्क क्यों पड़ता है? अलग-अलग आवेदन करने से पहले या बाद में, आदेश एक ही होना चाहिए – Rodolfo

+1

क्या आप हमें जो भी कोशिश कर रहे हैं और वास्तविक समस्या में चल रहे हैं, इसकी एक नमूना क्वेरी दिखा सकते हैं? –

उत्तर

5

दो बातें समझने के लिए:

  1. सामान्य शब्दों में, resultsets unordered हैं जब तक आप एक ORDER BY खंड निर्दिष्ट; इस सीमा तक कि आप non-strict order (यानी ORDER BY गैर-अद्वितीय कॉलम पर निर्दिष्ट करते हैं), ऑर्डर के तहत जो ऑर्डरिंग के बराबर हैं, वे ऑर्डर अनिश्चित हैं।

    मुझे संदेह है कि आप इस तरह के एक गैर-सख्त आदेश को निर्दिष्ट कर सकते हैं, जो आपकी समस्याओं का मूल है: सुनिश्चित करें कि आपके ऑर्डरिंग कॉलम के एक सेट पर ORDER BY निर्दिष्ट करके सख्त है जो प्रत्येक रिकॉर्ड को विशिष्ट रूप से पहचानने के लिए पर्याप्त है परिणाम में अपनी अंतिम स्थिति के बारे में परवाह है।

  2. DISTINCT may use GROUP BY, जो समूहबद्ध कॉलम द्वारा परिणामों का आदेश दिया जाता है; यानी, SELECT DISTINCT a, b, c FROM t एक परिणामसेट उत्पन्न करेगा जो प्रतीत होता है कि ORDER BY a, b, c लागू किया गया है। दोबारा, अपनी जरूरतों को पूरा करने के लिए पर्याप्त सख्त आदेश निर्दिष्ट करना इस प्रभाव को ओवरराइड करेगा।


ध्यान में रखते हुए, आपकी नई जानकारी के बाद मेरी बात # ऊपर 2, यह स्पष्ट है कि DISTINCT प्राप्त करने के लिए परिणाम समूहीकरण का असर यह तो गैर वर्गीकृत किया स्तंभ p.id द्वारा आदेश करने के लिए असंभव बना देता है; इसके बजाय, आप चाहते हैं:

SELECT t.* 
FROM  Threads t INNER JOIN Posts p ON t.id = p.threadid 
GROUP BY t.id 
ORDER BY MAX(p.id) DESC 
+0

बहुत बढ़िया, धन्यवाद, यह काम करता है। तो, बस पुष्टि करने के लिए, 'MAX() 'प्रत्येक समूह में' p.id' के अधिकतम मान का उपयोग करके तुलना करता है? –

+0

@ जेककिंग: यह सही है। – eggyal

+0

कूल, फिर से धन्यवाद। –

1

DISTINCT MySQL को आपके लिए एक रोसेट बनाने का तरीका बताता है, ORDER BY यह संकेत देता है कि यह पंक्ति कैसे प्रस्तुत की जानी चाहिए। तो जवाब है: DISTINCT पहले, ORDER BY अंतिम।

+3

लेकिन, हकीकत में, 'DISTINCT' को परिणामों को सॉर्ट करके कार्यान्वित किया जाता है ... इसलिए शायद नहीं तो ऑप्टिमाइज़र दोनों कार्यों के लिए एक ही ऑर्डरिंग का उपयोग करता है। – eggyal

+0

इस मामले में, उदासीन बिंदुओं के रूप में, एक [अपवाद] है (http://forge.mysql.com/w/images/a/ae/HowMySQLHandlesOrderGroupDistinct.pdf)। जब DISTINCT को ORDER BY के साथ समूहीकृत किया जाता है, तो यह सॉर्टिंग (filesort) पहले होता है। –

1

ऑर्डर जिसमें DISTINCT और ORDER BY लागू होते हैं, ज्यादातर मामलों में, अंतिम आउटपुट को प्रभावित नहीं करेंगे।

हालांकि, यदि आप GROUP BY का भी उपयोग करते हैं, तो यह अंतिम आउटपुट को प्रभावित करेगा। इस मामले में, ORDER BYGROUP BY के बाद किया जाता है, जो अप्रत्याशित परिणाम लौटाएगा (माना जाता है कि आप ग्रुपिंग से पहले सॉर्ट करने की अपेक्षा करते हैं)।

+0

['DISTINCT'' GROUP BY'] का उपयोग कर सकता है (http://dev.mysql.com/doc/en/distinct-optimization.html)। * समूहिंग करने से पहले * ऑर्डर करने से पहले यह निष्पादित करने में क्या होगा (इस बात को ध्यान में रखते हुए कि समेकित फ़ंक्शन के बिना असंगठित कॉलम का चयन अनिश्चित परिणामों में परिणाम - इस मामले में प्रासंगिक नहीं है, क्योंकि 'DISTINCT' इस तरह के कॉलम मौजूद नहीं है)? – eggyal

+0

@eggyal, यह मुद्दा 'DISTINCT' के साथ नहीं है, लेकिन' GROUP BY' और 'ORDER BY' के साथ है। यदि पंक्तियों को समूहीकृत किया गया है, लेकिन चयनित नहीं है, तो 'DISTINCT' कुछ भी मदद नहीं करता है, और क्वेरी "गलत" पंक्ति मान (उदा।' आईडी 'वापस कर सकती है, जिसे बाद में मूल्यों को पुनर्प्राप्त करने के लिए उपयोग किया जाता है)। – 0b10011

संबंधित मुद्दे