2014-07-21 7 views
9

this candidate answer में इस बात पर जोर है कि JOIN कुछ कुछ WHERE खंड शामिल है क्योंकि यह क्वेरी योजनाकार भ्रमित नहीं करता है और "व्यर्थ" नहीं है परिस्थितियों में LEFT JOIN से बेहतर है। दावा/धारणा यह है कि यह किसी के लिए स्पष्ट होना चाहिए।शामिल हों समझाओ बनाम वाम शामिल हों और जहां अधिक विस्तार से हालत प्रदर्शन संबंधी सुझाव देने

कृपया आगे की व्याख्या के लिए आगे बताएं या लिंक प्रदान करें।

+0

बेहतर? वे एक अलग उद्देश्य की सेवा करते हैं। जॉइन एक आंतरिक जुड़ाव है, बाएं जॉइन एक बाहरी जुड़ाव है (बाएं बाहरी जॉइन के समान ही)। आपके इरादों के आधार पर आप या तो बाहरी या आंतरिक शामिल होंगे। कहां स्थितियों के लिए WHERE खंड का उपयोग नहीं किया जाना चाहिए। इसका इस्तेमाल अन्य मानदंडों के लिए किया जाना चाहिए; अर्थात। छानने। –

+0

मैंने वहां जवाब पढ़ा है "चूंकि बाएं जॉइन (जहां के साथ) प्रभावी रूप से * एक इंटर्न जॉइन है, बस इसके बजाय एक INNER जॉइन का उपयोग करें।" मुझे यकीन नहीं है कि यह एक [विशिष्ट] क्वेरी प्लानर के लिए "भ्रमित" कैसे है, लेकिन यह मानव [पढ़ने: मेरी] खपत, IMOHO के लिए आदर्श से कम है। (एक INNER पर्याप्त होने पर क्रॉस जॉइन का उपयोग करने के लिए भी कहा जा सकता है, उदाहरण के लिए।) – user2864740

+0

एक बाएं जो किसी भी खंड के साथ जुड़ता है, जिसमें बाहरी जॉइन टेबल प्रभावी रूप से आंतरिक शामिल होता है। हालांकि अगर जहां खंड बाहरी जुड़ने वाली तालिका का उपयोग नहीं करता है, नहीं, यह मामला नहीं है। –

उत्तर

17

निम्नलिखित उदाहरण पर विचार करें। हमारे पास दो टेबल, डिपार्टमेंट्स और कर्मचारी हैं।

कुछ विभागों में अभी तक कोई कर्मचारी नहीं है।

यह क्वेरी भीतरी का उपयोग करता है में शामिल होने कि, 999 काम करता है पर विभाग कर्मचारी पाता है, यदि कोई हो, अन्यथा यह कुछ भी नहीं है (यहां तक ​​कि नहीं कर्मचारी या उसके नाम) दिखाता है:

select a.department_id, a.department_desc, b.employee_id, b.employee_name 
    from departments a 
    join employees b 
    on a.department_id = b.department_id 
where b.employee_id = '999' 

यह अगले क्वेरी एक का उपयोग करता है बाहरी जुड़ाव (विभागों और कर्मचारियों के बीच छोड़ दिया गया) और उस विभाग को पाता है जो कर्मचारी 999 के लिए काम करता है। हालांकि यह कर्मचारी के आईडी या उसके नाम को भी नहीं दिखाएगा, अगर वे किसी भी विभाग में काम नहीं करते हैं। यह WHERE खंड में उपयोग की जाने वाली बाहरी जुड़ी तालिका के कारण है। यदि कोई मिलान विभाग नहीं है, तो यह शून्य होगा (999 नहीं, भले ही 999 कर्मचारियों में मौजूद है)।

select a.department_id, a.department_desc, b.employee_id, b.employee_name 
    from departments a 
    left join employees b 
    on a.department_id = b.department_id 
where b.employee_id = '999' 

लेकिन इस प्रश्न को:

select a.department_id, a.department_desc, b.employee_id, b.employee_name 
    from departments a 
    left join employees b 
    on a.department_id = b.department_id 
    and b.employee_id= '999' 

अब मापदंड खंड पर है। तो अगर यह कर्मचारी किसी भी विभाग में काम नहीं करता है, तो भी वह वापस आ जाएगा (उसकी आईडी और नाम)। विभाग के कॉलम शून्य होंगे, लेकिन हमें परिणाम मिलेगा (कर्मचारी पक्ष)।

आपको लगता है कि आप कभी भी WHERE क्लॉज में बाहरी शामिल तालिका का उपयोग नहीं करना चाहेंगे, लेकिन यह आवश्यक नहीं है। आम तौर पर, ऊपर वर्णित कारण के लिए, हालांकि है।

मान लीजिए कि आप सभी विभागों के साथ कोई कर्मचारी नहीं चाहते हैं। तो फिर तुम निम्नलिखित है, जो में शामिल होने के एक बाहरी का उपयोग करता चला सकते हैं, और बाहरी में शामिल हो गए तालिका जहां खंड में प्रयोग किया जाता है:

select a.department_id, a.department_desc, b.employee_id 
    from departments a 
    left join employees b 
    on a.department_id = b.department_id 
where b.employee_id is null 

^^ नहीं कर्मचारियों के साथ विभागों दिखाता है।

उपरोक्त एकमात्र वैध कारण है कि आप ऑन क्लॉज के बजाय WHERE क्लॉज में बाहरी शामिल तालिका का उपयोग करना चाहते हैं (जो मुझे लगता है कि आपका प्रश्न क्या है; आंतरिक और बाहरी जुड़ने के बीच का अंतर पूरी तरह से है अलग विषय)।

यह देखने का एक अच्छा तरीका यह है: आप नल की अनुमति देने के लिए बाहरी जुड़ने का उपयोग करते हैं। फिर आप बाहरी शामिल होने का उपयोग क्यों करेंगे और कहेंगे कि एक क्षेत्र शून्य नहीं होना चाहिए और 'XYZ' के बराबर होना चाहिए? यदि कोई मान 'XYZ' होना चाहिए (शून्य नहीं), तो डेटाबेस को निर्देशों को वापस आने की अनुमति देने के लिए क्यों निर्देश दें? यह एक बात कहने जैसा है और फिर इसे बाद में ओवरराइड करना है।

11

प्रभावी रूप से WHERE परिस्थितियों और JOIN[INNER] JOIN के लिए स्थितियां PostgreSQL में 100% समकक्ष हैं। (प्रश्नों को पढ़ने और बनाए रखने के लिए आसान बनाने के लिए स्पष्ट JOIN स्थितियों का उपयोग करना अच्छा अभ्यास है)।

ही नहीं एक LEFT JOIN में शामिल होने के अधिकार के लिए एक मेज पर एक WHERE हालत के साथ संयुक्त के लिए सच है। LEFT JOIN का उद्देश्य शामिल होने के बाएं किनारे पर सभी पंक्तियों को सुरक्षित रखना है, दाएं तरफ एक मैच के अनियंत्रित। यदि कोई मिलान नहीं मिलता है, तो दाईं ओर कॉलम के लिए पंक्ति NULL मानों के साथ बढ़ा दी जाती है। The manual:

LEFT OUTER JOIN

सबसे पहले, एक आंतरिक शामिल होने के लिए किया जाता है। फिर, टी 1 में प्रत्येक पंक्ति के लिए जो टी 2 में किसी भी पंक्ति के साथ जुड़ने की स्थिति को पूरा नहीं करती है, एक पंक्ति में शामिल टी 2 के कॉलम में शून्य मानों के साथ जोड़ा जाता है। इस प्रकार, शामिल तालिका हमेशा टी 1 में प्रत्येक पंक्ति के लिए कम से कम एक पंक्ति है।

आप तो सही पक्ष पर तालिकाओं के स्तंभों पर एक WHERE शर्त लागू हैं, तो आप प्रभाव शून्य और जबरन LEFT JOIN बस अधिक बड़ी लागत एक और अधिक जटिल क्वेरी योजना की वजह से एक सादे JOIN की तरह काम करने के लिए, परिवर्तित।

कई शामिल तालिकाओं के साथ एक प्रश्न में, पोस्टग्रेस (या कोई भी आरडीबीएमएस) सर्वोत्तम (या यहां तक ​​कि एक अच्छी) क्वेरी योजना खोजने के लिए कठिन है। टेबल में शामिल होने के लिए सैद्धांतिक रूप से संभावित अनुक्रमों की संख्या फैक्टोरियल (!) बढ़ती है। पोस्टग्रेस कार्य के लिए "Generic Query Optimizer" का उपयोग करता है और इसे प्रभावित करने के लिए कुछ सेटिंग्स हैं।

उल्लिखित LEFT JOIN भ्रामक क्वेरी के साथ क्वेरी को बाधित करते हुए, क्वेरी प्लानर का काम कठिन बनाता है, मानव पाठकों के लिए भ्रामक है और आम तौर पर क्वेरी तर्क में त्रुटियों पर संकेत देता है। इस से उत्पन्न समस्याओं के लिए

कई संबंधित जवाब:

आदि

+0

यदि यह वास्तव में "अधिक व्यापक" है? आधुनिक प्रश्न योजनाकार - दी गई, मैं मुख्य रूप से SQL सर्वर का उपयोग करता हूं - मुझे प्रभावित करें। – user2864740

+3

यह कितना अंतर बनाता है यदि यह महंगा है या नहीं। यदि आप यह कहने जा रहे हैं कि टेबल एक्स पर मान कुछ (कुछ शून्य के अलावा) होना चाहिए तो आप टेबल एक्स के साथ बाहरी जुड़ने का उपयोग क्यों करेंगे? यदि कुछ भी हो, तो बस ऐसा न करें क्योंकि यह समझ में नहीं आता है। –

+0

@ user2864740: यह साधारण मामलों में ज्यादा मायने रखता नहीं है। यह जटिल मामलों में क्वेरी ऑप्टिमाइज़र का काम कठिन बनाता है, हालांकि।लेकिन जैसा कि ब्रायन ने टिप्पणी की: इसे किसी भी तरह से मत करो। यह मानव पाठक के लिए भी बहुत भ्रमित है। –

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