2009-01-12 7 views
40

Wikipedia कहता है:जब आप बाईं ओर के बजाय सही बाहरी सम्मिलन का उपयोग क्यों करेंगे?

"अभ्यास में, सुस्पष्ट अधिकार बाहरी शायद ही कभी इस्तेमाल किया जाता है में मिलती है क्योंकि वे हमेशा बाईं बाहरी साथ बदला जा सकता मिलती है और कोई अतिरिक्त सुविधा प्रदान करती हैं।"

क्या कोई ऐसी स्थिति प्रदान कर सकता है जहां उन्होंने सही नोटेशन का उपयोग करना पसंद किया है, और क्यों? मैं इसे कभी भी इस्तेमाल करने का कोई कारण नहीं सोच सकता। मेरे लिए, यह कभी चीजों को और स्पष्ट नहीं करेगा।

संपादित करें: मैं एक ओरेकल दिग्गज हूं जो नए साल के संकल्प को (+) वाक्यविन्यास से खुद को कम करने के लिए बना रहा है। मैं इसे सही करना चाहता हूं

+1

या, दूसरे शब्दों में कहें, तो आप इसे दाएं और बाएं (और पूर्ण) करना चाहते हैं :) –

उत्तर

27

सही बाहरी जॉइन का उपयोग करने के बारे में सोचने का एकमात्र कारण यह है कि आप अपने एसक्यूएल को अधिक आत्म-दस्तावेज बनाने की कोशिश करें।

आप संभावित रूप से उन प्रश्नों के लिए बाएं जुड़ने का उपयोग करना चाहते हैं जिनके पास एक-से-कई संबंधों के आश्रित (कई) पक्ष में शून्य पंक्तियां हैं और उन प्रश्नों पर सही शामिल है जो स्वतंत्र पक्ष में शून्य पंक्तियां उत्पन्न करते हैं।

यह जेनरेट कोड में भी हो सकता है या यदि दुकान की कोडिंग आवश्यकताएं FROM खंड में तालिकाओं की घोषणा का आदेश निर्दिष्ट करती हैं।

+2

+1, जवाब है, इवान के स्वीकार करेंगे अगर यह तुम्हारा संक्षेप माइकल, और। – DCookie

+1

हम बाएं बाहरी जुड़ने (जिस तरह से हम सही बाहरी जुड़ने का उपयोग कर रहे हैं) का उपयोग करके एक ही परिणाम प्राप्त कर सकते हैं। फिर सही जुर्माना या इसके विपरीत क्यों विकल्प है? –

5

एकमात्र बार जब मैं सही बाहरी जुड़ाव के बारे में सोचता हूं तो यह है कि अगर मैं पूर्ण जुड़ाव तय कर रहा हूं, और ऐसा ही हुआ कि मुझे दाईं ओर तालिका से सभी रिकॉर्ड रखने के परिणाम की आवश्यकता थी। यहां तक ​​कि आलसी होने के बावजूद, मैं शायद इतना नाराज हो जाऊंगा कि मैं बाएं शामिल होने के लिए इसे पुनर्व्यवस्थित कर दूंगा।

Wikipedia से यह उदाहरण दिखाता है कि मैं क्या मतलब है:

SELECT * 
FROM employee 
    FULL OUTER JOIN department 
     ON employee.DepartmentID = department.DepartmentID 

अगर तुम सिर्फ RIGHT के साथ शब्द FULL की जगह आप एक नया प्रश्न हैं, ON खंड के आदेश स्वैप करने के लिए बिना।

+0

पूर्ण विवरण कैसे पहले स्थान पर पहुंचे? बुरी तरह से भ्रमित पूछताछ सवाल? – dkretz

+3

'पूर्ण' का उद्देश्य है, और हमेशा "फिक्सिंग" की आवश्यकता नहीं होती है, और इसे 'राइट' के साथ बदलना एक ही चीज़ नहीं करता है। क्या होगा यदि आप कर्मचारी-विभाग असाइनमेंट को सत्यापित करने में मदद करने के लिए एक रिपोर्ट तैयार कर रहे हैं और उन विभागों को शामिल करना चाहते हैं जिनके पास कोई कर्मचारी और कर्मचारी नहीं हैं जिन्हें विभाग को सौंपा गया नहीं है? – utexaspunk

1

SQL कथन, सही होने के अलावा, पढ़ने के लिए के रूप में आसान है और अर्थपूर्ण ढंग से संभव के रूप में संक्षिप्त होना चाहिए (क्योंकि वे एकल परमाणु कार्यों का प्रतिनिधित्व करते हैं, और अपने मन उन्हें पूरी तरह से grok की अनपेक्षित परिणाम से बचने के लिए की जरूरत है।) कभी कभी एक अभिव्यक्ति है एक सही बाहरी शामिल होने के साथ और अधिक स्पष्ट रूप से कहा।

लेकिन किसी को हमेशा दूसरे में परिवर्तित किया जा सकता है, और अनुकूलक एक दूसरे के साथ भी करेगा।

थोड़ी देर के लिए, कम से कम प्रमुख rdbms उत्पादों में से एक केवल बाएं बाहरी जॉइन का समर्थन करता है। दाईं ओर बी फिर कार्यभार संभाला ए का मतलब है एक के बाईं ओर में है: (मेरा मानना ​​है कि यह MySQL था।)

+1

"कभी-कभी एक बाहरी अभिव्यक्ति के साथ एक अभिव्यक्ति अधिक स्पष्ट रूप से कहा जाता है।" जब मैं मामला हो सकता हूं तो मैं संघर्ष कर रहा हूं। एक वाक्यविन्यास का उपयोग क्यों करें जो मूल रूप से किसी अन्य के विपरीत है, अधिक सामान्य रूप से उपयोग किया जाता है? आपके पास कोई उदाहरण है? – DCookie

+1

नहीं। मैंने कभी भी सही निर्माता का उपयोग नहीं किया है: डी। – dkretz

7

बी अधिकार शामिल हों एक एक बाएं रूप में ही है बी

बी अधिकार शामिल हों शामिल हों एक पढ़ता डेटा सेट एक बाएं जॉइन बी

के समान ही कोई प्रदर्शन नहीं किया जा सकता है यदि आप बाएं जॉइन को सही तरीके से पुनर्व्यवस्थित करेंगे।

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

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

+0

+1, अगर यह आपके, जेकेके और इवान के सारांश का उत्तर देता है तो जवाब स्वीकार करेगा। – DCookie

2
SELECT * FROM table1 [BLANK] OUTER JOIN table2 ON table1.col = table2.col 

बदलें [रिक्त] के साथ:

वाम - (table2 मैचों के साथ रिकॉर्ड भी शामिल किए गए हैं) यदि आप table1 से सभी रिकॉर्ड चाहते हैं, भले ही वे एक col कि table2 के मेल खाता नहीं है

सही - अगर आप table2 से सभी रिकॉर्ड चाहते हैं, भले ही वे एक col कि table1 का मेल खाता नहीं है

पूर्ण (भी शामिल किए गए मैचों के साथ table1 रिकॉर्ड कर रहे हैं) - अगर आप table1 से और table2

से सभी रिकॉर्ड चाहते हैं

हर कोई किस बारे में बात कर रहा है? वे वही हैं? मुझे ऐसा नहीं लगता।

+2

आप हमेशा एक बाएं बाहरी जॉइन के साथ एक सही बाहरी जॉइन को प्रतिस्थापित कर सकते हैं जो एक ही उत्तर उत्पन्न करता है, और इसके विपरीत। – DCookie

+0

क्या आपका मतलब है कि आप केवल "बाएं" और "दाएं" शब्दों को स्वैप करें या क्या आपका मतलब है कि आप क्वेरी के सिंटैक्स के आसपास फ़्लॉप करते हैं? –

+3

आपको भी शामिल होने वाली तालिकाओं का क्रम बदलना होगा। – HLGEM

2

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

2
SELECT * FROM table_a 
INNER JOIN table_b ON .... 
RIGHT JOIN table_c ON .... 

और कैसे आप जल्दी/आसानी से भीतरी पहले 2 टेबल में शामिल होने और table_c में सभी पंक्तियों को सुनिश्चित करते हुए हमेशा चुने गए हैं table_c साथ शामिल हो सकते हैं?

+5

आप पहले table_c सूचीबद्ध कर सकते हैं और इसे दूसरों से जुड़ सकते हैं। – DCookie

+0

, यह पता लेखन @ मैट वाक्य रचना बराबर की तुलना में अधिक पठनीय लगता है: 'table_c से चुनें * वाम JOIN ( चुनें * table_a अंदरूनी शामिल हों पर .... table_b से) पर .... ' – 8forty

14

मैंने पहले कभी भी right join का उपयोग नहीं किया है और कभी नहीं सोचा था कि मुझे वास्तव में इसकी आवश्यकता हो सकती है, और यह थोड़ा अप्राकृतिक लगता है। लेकिन उसके बाद मैं इसके बारे में सोचा है, यह स्थिति में वास्तव में उपयोगी है, जब आप कई तालिकाओं के चौराहे के साथ एक मेज में शामिल होने के बाहरी की जरूरत हो सकती है, तो आप इस तरह टेबल है:

enter image description here

और प्राप्त करना चाहते हैं इस तरह परिणाम:

enter image description here

या, एसक्यूएल (एमएस एसक्यूएल सर्वर) में:

declare @temp_a table (id int) 
declare @temp_b table (id int) 
declare @temp_c table (id int) 
declare @temp_d table (id int) 

insert into @temp_a 
select 1 union all 
select 2 union all 
select 3 union all 
select 4 

insert into @temp_b 
select 2 union all 
select 3 union all 
select 5 

insert into @temp_c 
select 1 union all 
select 2 union all 
select 4 

insert into @temp_d 
select id from @temp_a 
union 
select id from @temp_b 
union 
select id from @temp_c 

select * 
from @temp_a as a 
    inner join @temp_b as b on b.id = a.id 
    inner join @temp_c as c on c.id = a.id 
    right outer join @temp_d as d on d.id = a.id 

id   id   id   id 
----------- ----------- ----------- ----------- 
NULL  NULL  NULL  1 
2   2   2   2 
NULL  NULL  NULL  3 
NULL  NULL  NULL  4 
NULL  NULL  NULL  5 

इसलिए यदि आप left join पर स्विच करते हैं, तो परिणाम समान नहीं होंगे।

select * 
from @temp_d as d 
    left outer join @temp_a as a on a.id = d.id 
    left outer join @temp_b as b on b.id = d.id 
    left outer join @temp_c as c on c.id = d.id 

id   id   id   id 
----------- ----------- ----------- ----------- 
1   1   NULL  1 
2   2   2   2 
3   3   3   NULL 
4   4   NULL  4 
5   NULL  5   NULL 

अधिकार के बिना शामिल होने के ऐसा करने के लिए एक ही रास्ता आम तालिका अभिव्यक्ति या सबक्वेरी

select * 
from @temp_d as d 
    left outer join (
     select * 
     from @temp_a as a 
      inner join @temp_b as b on b.id = a.id 
      inner join @temp_c as c on c.id = a.id 
    ) as q on ... 
+4

आप किसी चयन को घोंसला करने की आवश्यकता नहीं है, आप इसके बदले में शामिल हो सकते हैं: '@ememp_d एएस डी बाएं बाहरी जॉइन (temp_a के रूप में एक INNER JOIN @temp_b AS b b.id = a.id INNER JOIN @temp_c AS c ON c.id = a.id) a.id = d.id' पर। (ब्रैकेट अनावश्यक हैं, उन्हें केवल पठनीयता के लिए जोड़ा जाता है।) यह सच है, हालांकि, ऐसे लोग हैं जो अनिश्चित हैं कि वे कौन से सिंटैक्स से घृणा करते हैं, घोंसले में शामिल होते हैं या सही बाहरी जुड़ते हैं, इसलिए यह संभव है कि सही जुड़ें * उनके लिए कम बुरी तरह *। :) –

+0

अच्छा, मैंने कभी भी नेस्टेड जॉइन सिंटैक्स का उपयोग नहीं किया :) –

2

उपयोग करने के लिए मैं वास्तव में सही पर ज्यादा लगता है में शामिल होने के लिए किया था नहीं किया है, लेकिन मुझे लगता है कि मैं एसक्यूएल प्रश्न लिखने के लगभग 20 वर्षों में नहीं है, एक का उपयोग करने के लिए एक ध्वनि औचित्य में आते हैं। मैंने निश्चित रूप से उनमें से बहुत से देखा है, मुझे लगता है कि डेवलपर्स ने बिल्ट-इन क्वेरी बिल्डर्स का उपयोग किया है।

जब भी मुझे सामना करना पड़ता है, मैंने इसे खत्म करने के लिए क्वेरी को फिर से लिखा है - मैंने पाया है कि अगर आपको कुछ समय के लिए क्वेरी नहीं मिली है तो उन्हें सीखने या फिर से सीखने के लिए बहुत अधिक अतिरिक्त मानसिक ऊर्जा की आवश्यकता है और यह प्रश्न खोने या गलत परिणामों को वापस करने के इरादे के लिए असामान्य नहीं है - और आमतौर पर यह गलतता है जिसके कारण मुझे समीक्षा करने के लिए अनुरोध किया गया कि प्रश्न क्यों काम नहीं कर रहे थे।

इसके बारे में सोचने के बाद, एक बार जब आप सही-जुड़ने का परिचय देते हैं, तो अब आपके पास तर्क की प्रतिस्पर्धी शाखाओं पर विचार करना होगा, जो बीच में मिलना आवश्यक है। यदि अतिरिक्त आवश्यकताओं/शर्तों को पेश किया जाता है, तो इन दोनों शाखाओं को आगे बढ़ाया जा सकता है और अब आपके पास यह सुनिश्चित करने के लिए अधिक जटिलता है कि एक शाखा गलत परिणामों को जन्म नहीं दे रही है।

आगे, एक बार जब आप सही शामिल हो जाते हैं, तो बाद में क्वेरी पर काम करने वाले अन्य कम अनुभवी डेवलपर क्वेरी के दाएं भाग में भाग लेने के लिए अतिरिक्त तालिकाओं पर बोल्ट कर सकते हैं और ऐसा करने में, प्रतिस्पर्धी तर्क प्रवाह का विस्तार करना बीच में मिलने की जरूरत है; या मैंने देखा है कि कुछ मामलों में, घोंसले के विचारों को शुरू करना क्योंकि वे मूल तर्क को छूना नहीं चाहते हैं, शायद कुछ हद तक, ऐसा इसलिए है क्योंकि वे तर्क या व्यापार नियमों को समझ नहीं सकते हैं जो तर्क को चलाते थे।

0

कुछ SQL डेटाबेस में, ऑप्टिमाइज़र संकेत हैं जो ऑप्टिमाइज़र को ऑर्डर में तालिका में शामिल होने के लिए बताते हैं जिसमें वे FROM खंड में दिखाई देते हैं - उदा। ओरेकल में /*+ORDERED */। कुछ सरल कार्यान्वयन में, यह एकमात्र निष्पादन योजना भी उपलब्ध हो सकती है।

ऐसे मामलों में FROM खंड तालिकाओं में तालिकाओं का क्रम RIGHT JOIN उपयोगी हो सकता है।

0

मुझे लगता है कि यदि आप इस मामले में सही शामिल नहीं हैं तो यह मुश्किल है। ओरेकल के साथ पूर्व।

with a as(
    select 1 id, 'a' name from dual union all 
    select 2 id, 'b' name from dual union all 
    select 3 id, 'c' name from dual union all 
    select 4 id, 'd' name from dual union all 
    select 5 id, 'e' name from dual union all 
    select 6 id, 'f' name from dual 
), bx as(
    select 1 id, 'fa' f from dual union all 
    select 3 id, 'fb' f from dual union all 
    select 6 id, 'f' f from dual union all 
    select 6 id, 'fc' f from dual 
) 
select a.*, b.f, x.f 
from a left join bx b on a.id = b.id 
right join bx x on a.id = x.id 
order by a.id 
+0

'बी। एक्स, बीएफ, एक्सएफ से बीएक्स एक्स बाएं बाहरी में एक .id = x.id पर शामिल हों b.id = a पर bx b में शामिल हों एआईडी द्वारा आदेश – JohnLBevan

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