एसक्यूएल में ज्वाइन ऑर्डर क्या मायने रखता है?


189

प्रदर्शन की अवहेलना, क्या मुझे नीचे दिए गए प्रश्न A और B से समान परिणाम मिलेगा? सी और डी के बारे में कैसे?

-- A
select *
from   a left join b
           on <blahblah>
       left join c
           on <blahblan>


-- B
select *
from   a left join c
           on <blahblah>
       left join b
           on <blahblan>  

-- C
select *
from   a join b
           on <blahblah>
       join c
           on <blahblan>


-- D
select *
from   a join c
           on <blahblah>
       join b
           on <blahblan>  

11
क्या है <blahblah>? क्या आप A से B और A से C में शामिल हो रहे हैं, या आप A से B और B से C में शामिल हो रहे हैं?
बेनी 23

2
हाय बेनी, मेरे सवाल में कोड एक अमूर्त है। मुझे ए से बी या ए से सी में शामिल होने का कोई मलाल नहीं है, मैं सिर्फ यह जानना चाहता हूं कि सिंटेक्स ऐसा ही होगा जो समान परिणाम प्रदान करेगा।
सिर्फ एक शिक्षार्थी

जवाबों:


225

के लिए INNERमिलती है, नहीं, आदेश नहीं फर्क पड़ता है। प्रश्नों जब तक आप से अपने चयन को बदलने के रूप में एक ही परिणाम दिखाएँगे, SELECT *करने के लिए SELECT a.*, b.*, c.*


के लिए LEFT, RIGHTया FULL) OUTERजुड़ता है, हाँ, आदेश मायने रखता है - और ( अद्यतन ) चीजें बहुत अधिक जटिल हैं।

सबसे पहले, बाहरी जोड़ सराहनीय नहीं हैं, इसलिए a LEFT JOIN bऐसा नहीं हैb LEFT JOIN a

बाहरी जोड़ या तो सहयोगी नहीं हैं, इसलिए आपके उदाहरणों में जो दोनों (कम्यूटेटिविटी और एसोसिएटिविटी) गुण शामिल हैं:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id
  LEFT JOIN c
    ON c.ac_id = a.ac_id

के बराबर है :

a LEFT JOIN c 
    ON c.ac_id = a.ac_id
  LEFT JOIN b
    ON b.ab_id = a.ab_id

परंतु:

a LEFT JOIN b 
    ON  b.ab_id = a.ab_id
  LEFT JOIN c
    ON  c.ac_id = a.ac_id
    AND c.bc_id = b.bc_id

के बराबर नहीं है :

a LEFT JOIN c 
    ON  c.ac_id = a.ac_id
  LEFT JOIN b
    ON  b.ab_id = a.ab_id
    AND b.bc_id = c.bc_id

एक और (उम्मीद के मुताबिक सरल) सहानुभूति उदाहरण। इसे इस प्रकार समझें (a LEFT JOIN b) LEFT JOIN c:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id          -- AB condition
 LEFT JOIN c
    ON c.bc_id = b.bc_id          -- BC condition

यह इसके बराबर है a LEFT JOIN (b LEFT JOIN c):

a LEFT JOIN  
    b LEFT JOIN c
        ON c.bc_id = b.bc_id          -- BC condition
    ON b.ab_id = a.ab_id          -- AB condition

केवल इसलिए कि हमारे पास "अच्छी" ONस्थितियां हैं। दोनों ON b.ab_id = a.ab_idऔर c.bc_id = b.bc_idसमानता जाँच हैं और NULLतुलना शामिल नहीं है ।

यहां तक ​​कि आपके पास अन्य ऑपरेटरों या अधिक जटिल लोगों के साथ स्थितियां भी हो सकती हैं जैसे: ON a.x <= b.xया ON a.x = 7या ON a.x LIKE b.xया ON (a.x, a.y) = (b.x, b.y)और दोनों प्रश्न अभी भी समतुल्य होंगे।

हालांकि, इनमें से कोई भी शामिल है IS NULLया एक फ़ंक्शन जो नल से संबंधित है COALESCE(), उदाहरण के लिए, यदि स्थिति थी b.ab_id IS NULL, तो दोनों प्रश्न समतुल्य नहीं होंगे।


3
यह कहना अधिक सही है कि बाहरी जुड़ाव तब तक सहयोगी होता है जब तक कि न तो विधेय को एक पंक्ति से संतुष्ट किया जा सकता है जिसमें एक तालिका के सभी कॉलम NULL हैं, यह कहने की तुलना में कि यह संबद्ध है जब तक कि विधेयकों में NULL शामिल नहीं है या 'एक फ़ंक्शन जो नल से संबंधित है'। एक आसानी से एक विधेय की कल्पना कर सकता है जो पूर्व विवरण को संतुष्ट करता है लेकिन बाद के नहीं, जैसे a.somecol > 0 OR b.someothercol > 0; सहानुभूति उस स्थिति के लिए विफल हो सकती है।
मार्क अमेरी

लेकिन हाँ, मुझे लगता है कि तकनीकी रूप से यह कहना सही है कि OUTER JOIN सहयोगी है, जब तक कि विधेय मेरे द्वारा बताई गई शर्तों में से किसी एक को भी संतुष्ट नहीं करता है: stackoverflow.com/questions/20022196/… (जिनमें से सबसे पहले संघात को तोड़ता है INNER JOINs के लिए, लेकिन इसे तोड़ने के लिए इतना सस्ता और स्पष्ट तरीका है कि शायद यह ध्यान देने योग्य नहीं है।) यह भी इंगित करने योग्य है कि JOIN का सबसे आम प्रकार - एक विदेशी कुंजी पर शामिल होना - उन स्थितियों में से किसी को भी संतुष्ट नहीं करता है। और इस प्रकार अच्छा और साहचर्य है।
मार्क अमेरी

1
@MarkAmery धन्यवाद, मैं उस बिंदु पर अपने वाक्यों को संरचित करने में एक कठिन समय बिता रहा था (और मैंने पहले से ही आपके उस उत्तर को
उखाड़ दिया है

ypercube मैं एक INNER JOINऔर एक निम्नलिखित है LEFT JOIN। यह है कि पहली क्वेरी की तरह होगा काम करता है Filterके आधार पर रिकॉर्ड INNER JOINऔर फिर लागू होगी LEFT JOINकरने के लिए Filteredरिकॉर्ड?
मुहम्मद बाबर

वास्तव में, सभी ज्वाइन टाइप्स एसोसिएटिव होते हैं , जैसा कि एसक्यूएल मानक द्वारा निर्दिष्ट किया गया है और एसोसिएटिविटी की गणितीय परिभाषा के अनुसार, लेकिन वे सहयोगी नहीं दिखते हैं क्योंकि कोष्ठक को पुनर्व्यवस्थित करने के लिए ONक्लॉज को स्थानांतरित करने की आवश्यकता होती है (अर्थात "स्पेसिफिकेशन में शामिल हों") एक नए स्थान पर। । यह केवल वाक्यविन्यास है, हालांकि। यदि आप संबंधपरक बीजगणित संकेतन का उपयोग करते हैं (जहां जुड़ने वाले ऑपरेटर से जुड़ने के लिए स्पेसिफिकेशन नीचे रखा गया है), तो संबद्धता अधिक स्पष्ट हो जाती है। आपका तर्क केवल यह दर्शाता है कि बाहरी जुड़ाव कम्यूटेटिव नहीं है , जो सही है
लुकास ईडर

4

नियमित जॉइन के लिए, यह नहीं है। TableA join TableBउसी निष्पादन योजना का निर्माण करेंगे TableB join TableA(ताकि आपके C और D उदाहरण समान होंगे)

बाएं और दाएं से जुड़ता है। TableA left Join TableBकी तुलना में अलग है TableB left Join TableA, लेकिन इसकी तुलना में समान हैTableB right Join TableA


4
यह केवल कम्यूटिविटी को संबोधित करता है, लेकिन प्रश्न में दिए गए उदाहरण बताते हैं कि पूछने वाले की सहयोगीता में रुचि है। ypercube का उत्तर दोनों को संबोधित करता है।
मार्क अमेरी

2

यदि आप B से जुड़ने से पहले B से किसी फ़ील्ड पर C जुड़ने का प्रयास करते हैं, तो:

SELECT A.x, A.y, A.z FROM A 
   INNER JOIN C
       on B.x = C.x
   INNER JOIN b
       on A.x = B.x

आपकी क्वेरी विफल हो जाएगी, इसलिए इस मामले में आदेश मायने रखता है।


हाँ यह सही है, सही उत्तर में संशोधन होना चाहिए।
निर पेंगस

-2

ओरेकल ऑप्टिमाइज़र अंदरूनी जुड़ने के लिए तालिकाओं के क्रम में शामिल होने का चयन करता है। ऑप्टिमाइज़र केवल साधारण क्लॉज़ में तालिकाओं के सम्मिलित क्रम को चुनता है। यू अपनी वेबसाइट में ओरेकल दस्तावेज की जांच कर सकते हैं। और बाएं, दाएं बाहरी के लिए सबसे अधिक मतदान में शामिल होने का उत्तर सही है। ऑप्टिमाइज़र इष्टतम जुड़ने के आदेश के साथ-साथ प्रत्येक तालिका के लिए इष्टतम सूचकांक चुनता है। ज्वाइन ऑर्डर प्रभावित कर सकता है कि कौन सा इंडेक्स सबसे अच्छा विकल्प है। ऑप्टिमाइज़र एक तालिका के लिए पहुंच पथ के रूप में एक इंडेक्स चुन सकता है यदि वह आंतरिक तालिका है, लेकिन ऐसा नहीं है कि यह बाहरी तालिका है (और आगे कोई योग्यता नहीं है)।

ऑप्टिमाइज़र केवल साधारण क्लॉज़ में तालिकाओं के सम्मिलित क्रम को चुनता है। JOIN कीवर्ड का उपयोग करने वाले अधिकांश जॉइन को सरल जॉइन में समतल कर दिया जाता है, इसलिए ऑप्टिमाइज़र अपने जॉइन ऑर्डर को चुनता है।

आशावादी बाहरी जोड़ के लिए सम्मिलित आदेश का चयन नहीं करता है; यह कथन में निर्दिष्ट आदेश का उपयोग करता है।

किसी ज्वाइन ऑर्डर का चयन करते समय, ऑप्टिमाइज़र को ध्यान में रखना होता है: प्रत्येक टेबल का आकार प्रत्येक टेबल पर उपलब्ध इंडेक्स, चाहे टेबल पर कोई इंडेक्स किसी विशेष जॉइन ऑर्डर में उपयोगी हो, प्रत्येक टेबल के लिए पंक्तियों और पेजों की संख्या को स्कैन करने के लिए आदेश में शामिल हों

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.