INNER JOIN और LEFT SEMI JOIN में अंतर


85

एक बीच क्या अंतर है INNER JOINऔर LEFT SEMI JOIN?

नीचे के परिदृश्य में, मुझे दो अलग-अलग परिणाम क्यों मिल रहे हैं?

INNER JOINपरिणाम सेट एक बहुत बड़ा है। क्या कोई समझा सकता है? मैं कोशिश कर रहा हूं table_1कि केवल नाम सामने आए table_2

SELECT name
FROM table_1 a
    INNER JOIN table_2 b ON a.name=b.name

SELECT name
FROM table_1 a
    LEFT SEMI JOIN table_2 b ON (a.name=b.name)

2
आंतरिक जुड़ाव आपके लक्ष्य को प्राप्त करेगा। जब तक मैंने इस प्रश्न को नहीं देखा, तब तक मैंने एक सेमी जॉइन के बारे में नहीं सुना था।
दान ब्रुकुक

left semi joinकी तुलना में अधिक पंक्तियों लौट जाना चाहिए inner join
गॉर्डन लिनॉफ़

1
inner joinडेटा वापस आ जाएगी तभी दोनों तालिकाओं के बीच एक मैच है। left joinभले ही कोई एक मिलान रिकॉर्ड दूसरी तालिका में पाया जाता है पहली तालिका से डेटा वापस आ जाएगी।
j03z

11
@GordonLinoff जरूरी नहीं, एक LEFT SEMI JOINही बाईं ओर से एक पंक्ति लौटेगा, भले ही दाहिने में कई मैच हों। एक INNER JOINअगर वहाँ सही पर एक से अधिक मिलान कर रहे हैं कई पंक्तियों वापस आ जाएगी।
D स्टेनली

1
@ j03z जो सही नहीं हो सकता। यदि बाएं हेमी-ज्वाइन का उद्देश्य केवल 1 है) तो बाईं टेबल में केवल जानकारी वापस करना (जैसा कि अन्य लोगों ने कहा है) और 2) मैच की परवाह किए बिना, टेह लेफ्ट टेबल से पंक्तियों को वापस करने के लिए (जैसा कि मुझे लगता है कि आप कहते हैं) बस मूल बाईं मेज - कोई भी आवश्यक नहीं है कि पूरा करने के लिए। मुझे लगता है कि दूसरों को सही होना चाहिए कि बाएं हेमी-जॉइन 1) केवल बाएं टेबल से कॉलम लौटाता है, 2) केवल उन पंक्तियों को लौटाता है जिनके दाएं टेबल में एक मैच होता है, और 3) बाईं ओर से एक पंक्ति को एक या एक के लिए वापस कर देगा अधिक मैच।
कार्ल जी।

जवाबों:


126

एक INNER JOINदोनों तालिकाओं से स्तंभ से डेटा वापस कर सकते हैं और दोनों तरफ के रिकॉर्ड के मूल्यों नकल कर सकते हैं और अधिक से अधिक एक मैच है। A LEFT SEMI JOINकेवल बाएं-हाथ की तालिका से कॉलम वापस कर सकता है, और बाएं-हाथ की तालिका से प्रत्येक रिकॉर्ड में से एक को प्राप्त करता है जहां दाएं-हाथ की तालिका में (एक या अधिक मैच की संख्या होती है) (मैचों की संख्या की परवाह किए बिना)। यह (मानक SQL में) के बराबर है:

SELECT name
FROM table_1 a
WHERE EXISTS(
    SELECT * FROM table_2 b WHERE (a.name=b.name))

यदि दाएं हाथ के कॉलम में कई मिलान पंक्तियां हैं, तो INNER JOINप्रत्येक तालिका के लिए एक पंक्ति दाएं मेज पर वापस आ जाएगी, जबकि बाईं ओर LEFT SEMI JOINकी पंक्तियों की संख्या की परवाह किए बिना, केवल एक पंक्ति बाईं तालिका से वापस आती है। इसीलिए आपको अपने परिणाम में एक अलग संख्या दिखाई दे रही है।

मैं तालिका 1 के भीतर नाम प्राप्त करने का प्रयास कर रहा हूं जो केवल तालिका 2 में दिखाई देता है।

फिर LEFT SEMI JOINउपयोग करने के लिए उपयुक्त क्वेरी है।


क्या वास्तव में ऐसा है LEFT SEMI JOIN? सिर्फ एक नहीं है SEMI JOIN? वहाँ कोई मतलब नहीं है RIGHT SEMI JOIN, वहाँ है?
एरिक

में हाइव , हाँ।
डी स्टेनली

1
महान जवाब बस मैं क्या देख रहा था। मैं उत्तर को अधिक सटीक रूप से वाक्यांशित करूंगा: "... एक INNER JOIN दाएं तालिका की प्रत्येक मिलान पंक्ति के लिए एक पंक्ति लौटाएगा , जबकि एक LEFT SEMI JOIN ...
Barak1731475

2
इस के विपरीत एक बाईं ओर जॉय है जो कुंजी के अनुसार बाईं तालिका में दाएं तालिका से डेटा को फ़िल्टर करता है। सोचा था कि मैं इस सोने की डली को किसी ऐसे व्यक्ति के यहाँ छोड़ जाऊँगा जो शायद देख रहा हो!
शांतनुसिंघल

64

मान लें कि केवल 2 कॉलम (आईडी, डेटा) और निम्न डेटा के साथ 2 टेबल टेबलए और टेबलबी हैं:

TableA:

+----+---------+
| Id |  Data   |
+----+---------+
|  1 | DataA11 |
|  1 | DataA12 |
|  1 | DataA13 |
|  2 | DataA21 |
|  3 | DataA31 |
+----+---------+

TableB:

+----+---------+
| Id |  Data   |
+----+---------+
|  1 | DataB11 |
|  2 | DataB21 |
|  2 | DataB22 |
|  2 | DataB23 |
|  4 | DataB41 |
+----+---------+

इनर जुड़ें स्तंभ पर Idदोनों तालिकाओं और केवल मिलान रिकॉर्ड से कॉलम वापस आ जाएगी:

.----.---------.----.---------.
| Id |  Data   | Id |  Data   |
:----+---------+----+---------:
|  1 | DataA11 |  1 | DataB11 |
:----+---------+----+---------:
|  1 | DataA12 |  1 | DataB11 |
:----+---------+----+---------:
|  1 | DataA13 |  1 | DataB11 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB21 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB22 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB23 |
'----'---------'----'---------'

लेफ्ट जॉइन (या लेफ्ट आउटर जॉइन्ट) Idकॉलम पर दोनों टेबल से कॉलम लौटाएंगे और बाएं टेबल से रिकॉर्ड के साथ मिलान रिकॉर्ड करेंगे (राइट टेबल से नल मान)

.----.---------.----.---------.
| Id |  Data   | Id |  Data   |
:----+---------+----+---------:
|  1 | DataA11 |  1 | DataB11 |
:----+---------+----+---------:
|  1 | DataA12 |  1 | DataB11 |
:----+---------+----+---------:
|  1 | DataA13 |  1 | DataB11 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB21 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB22 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB23 |
:----+---------+----+---------:
|  3 | DataA31 |    |         |
'----'---------'----'---------'

कॉलम में राइट जॉइन (या राइट आउटर जॉइन) Idदोनों टेबल से कॉलम लौटाएगा और राइट टेबल से रिकॉर्ड के साथ मिलान रिकॉर्ड करेगा (बाएं टेबल से नल मान)

┌────┬─────────┬────┬─────────┐
│ Id │  Data   │ Id │  Data   │
├────┼─────────┼────┼─────────┤
│  1 │ DataA11 │  1 │ DataB11 │
│  1 │ DataA12 │  1 │ DataB11 │
│  1 │ DataA13 │  1 │ DataB11 │
│  2 │ DataA21 │  2 │ DataB21 │
│  2 │ DataA21 │  2 │ DataB22 │
│  2 │ DataA21 │  2 │ DataB23 │
│    │         │  4 │ DataB41 │
└────┴─────────┴────┴─────────┘

पूर्ण बाहरी जुड़ें स्तंभ पर Idसही टेबल से बाईं मेज से रिकॉर्ड (सही मेज से अशक्त मान) और रिकॉर्ड (बाएं मेज से अशक्त मान) के साथ दोनों तालिकाओं से कॉलम और मिलान रिकॉर्ड वापस आ जाएगी:

╔════╦═════════╦════╦═════════╗
║ Id ║  Data   ║ Id ║  Data   ║
╠════╬═════════╬════╬═════════╣
║  - ║         ║    ║         ║
║  1 ║ DataA11 ║  1 ║ DataB11 ║
║  1 ║ DataA12 ║  1 ║ DataB11 ║
║  1 ║ DataA13 ║  1 ║ DataB11 ║
║  2 ║ DataA21 ║  2 ║ DataB21 ║
║  2 ║ DataA21 ║  2 ║ DataB22 ║
║  2 ║ DataA21 ║  2 ║ DataB23 ║
║  3 ║ DataA31 ║    ║         ║
║    ║         ║  4 ║ DataB41 ║
╚════╩═════════╩════╩═════════╝

लेफ्ट सेमी ज्वाइन कॉलम में Idलेफ्ट टेबल से कॉलम ही लौटेगा और मिलान केवल लेफ्ट टेबल से होगा:

┌────┬─────────┐
│ Id │  Data   │
├────┼─────────┤
│  1 │ DataA11 │
│  1 │ DataA12 │
│  1 │ DataA13 │
│  2 │ DataA21 │
└────┴─────────┘

मैं इसे "LEFT INNER Join" कहता था।
अंशुल जोशी

INNER JOIN परिणाम से A. * का DISTINCT LEFT SEMI JOIN के बराबर है।
तेजा

4
डिस्टिंक्ट सुरक्षित नहीं लगता, मान लीजिए कि ए में दो समान रिकॉर्ड हैं।
डेनिस जहीरुद्दीन

यहां तक ​​कि अगर परिणाम समान होता है, तो DISTINCT का उपयोग करके EXISTS की तुलना में अधिक महंगा योजना हो सकती है
manotheshark

32

हाइव में कोशिश की और नीचे उत्पादन मिला

तालिका एक

1, wqe, चेन्नई, भारत

2, स्टू, सेलम, भारत

3, मिया, बंगलौर, भारत

4, yepie, न्यूयॉर्क, संयुक्त राज्य अमेरिका

तालिका 2

1, wqe, चेन्नई, भारत

2, स्टू, सेलम, भारत

3, मिया, बंगलौर, भारत

5, चॉपी, लॉस एंजेल्स, यूएसए

आंतरिक रूप से जुड़ा

का चयन करें * से तालिका 1 में शामिल हों तालिका 2 पर शामिल करें (table1.id = table2.id);

1 विकी चेन्नई भारत 1 विकी चेन्नई भारत

2 स्टु सलाम भारत 2 स्टु सलाम भारत

3 मिया बैंग्लोर भारत 3 मिया बैंगलौर भारत

बाँया जोड़

सेलेक्ट करें * FROM table1 LEFT JOIN table2 ON (table1.id = table2.id);

1 विकी चेन्नई भारत 1 विकी चेन्नई भारत

2 स्टु सलाम भारत 2 स्टु सलाम भारत

3 मिया बैंग्लोर भारत 3 मिया बैंगलौर भारत

4 yepie newyork यूएसए NULL NULL NULL NULL

लेफ्ट सेमी जॉइन करें

का चयन करें * से तालिका 1 LEFT SEMI JOIN table2 ON (table1.id = table2.id);

1 विकी चेन्नई भारत

2 स्टु सलाम भारत

3 मिया बंगलौर भारत

नोट: केवल बाएँ तालिका में रिकॉर्ड प्रदर्शित किए जाते हैं जबकि बाएँ के लिए दोनों तालिका रिकॉर्ड सम्मिलित हों

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