SQL JOIN और विभिन्न प्रकार के JOINs


244

SQL क्या है JOINऔर विभिन्न प्रकार क्या हैं?

जवाबों:


330

W3schools से एक चित्रण :


INNER JOIN - केवल रिकॉर्ड जो दोनों तालिकाओं में स्थिति से मेल खाते हैं


LEFT JOIN - तालिका 1 की स्थिति से मेल खाने वाले रिकॉर्ड के साथ तालिका 1 से सभी रिकॉर्ड


राइट जॉइन - टेबल 1 से रिकॉर्ड के साथ संयोजन में तालिका 2 से सभी रिकॉर्ड जो स्थिति से मेल खाते हैं


फुल ओटर जॉय - लेफ्ट और राईट आउटर दोनों का कॉम्बिनेशन क्लॉज से मेल खाता है लेकिन दोनों टेबल्स को संरक्षित करता है



27
@KNU w3fools को क्रेडिट देना चाहिए जहां से उन्होंने चित्रों के लिए विचार लिया है। एसक्यूएल का एक दृश्य देखें जेफ एटवुड (हां, जो एसओ सह-लेखक हैं) और लिगया टरमेल द्वारा लिंक किए गए लेख से जहां जेफ को यह विचार मिला और इसे समझा।
ypercube y

2
@ लेवी बाएँ और दाएँ जोड़ समान हैं, यदि आपको परेशान नहीं किया जाता है कि प्राथमिक तालिका में शामिल होने पर आधारित है।
अनूप

2
@philipxy: यह एक अजीब परिभाषा है (भले ही आप सही हों)। लेकिन मैं इसके बजाय दूसरे रास्ते पर जाऊंगा और क्रॉस जॉइन के साथ शुरू करूंगा और फिर इसके ऊपर "बिल्ड" इनर जॉइन करूंगा। आखिरकार, क्रॉस की मात्र अवधारणा इन अनौपचारिक और गलत वेन आरेख दृश्यों को अमान्य करती है ...
लुकास ईडर

1
इन चित्रों से यह प्रतीत होता है कि मिलन पूर्ण बाहरी जुड़ाव के समान है और प्रतिच्छेदन भी आंतरिक जुड़ाव के समान है जो अब तक ज्ञात नहीं है।
ताकतवर

1
@DevDave, क्योंकि लोकप्रिय धारणा के विपरीत - एक तस्वीर एक हजार शब्दों के लायक नहीं है। अगला जवाब देखें
संकरो

248

क्या है SQL JOIN?

SQL JOIN दो या अधिक डेटाबेस तालिकाओं से डेटा पुनर्प्राप्त करने की एक विधि है।

अलग-अलग SQL JOINएस क्या हैं ?

कुल पाँच JOINs हैं। वो हैं :

  1. JOIN or INNER JOIN
  2. OUTER JOIN

     2.1 LEFT OUTER JOIN or LEFT JOIN
     2.2 RIGHT OUTER JOIN or RIGHT JOIN
     2.3 FULL OUTER JOIN or FULL JOIN

  3. NATURAL JOIN
  4. CROSS JOIN
  5. SELF JOIN

1. शामिल हों या शामिल हों:

इस तरह के एक में JOIN, हम सभी रिकॉर्ड प्राप्त करते हैं जो दोनों तालिकाओं में स्थिति से मेल खाते हैं, और दोनों तालिकाओं में रिकॉर्ड जो मेल नहीं खाते हैं, रिपोर्ट नहीं किए जाते हैं।

दूसरे शब्दों में, INNER JOINइस तथ्य पर आधारित है कि: केवल मिलान प्रविष्टियों में तालिकाएँ सूचीबद्ध नहीं की जानी चाहिए।

ध्यान दें कि एक JOINकिसी अन्य के बिना JOIN(जैसे कीवर्ड INNER, OUTER, LEFT, आदि) एक है INNER JOIN। दूसरे शब्दों में,JOIN लिए एक Syntactic चीनी है INNER JOIN(देखें: JOIN और INNER JOIN के बीच अंतर )।

2. OUTER JOIN:

OUTER JOIN retrieves

या तो, एक तालिका से मिलान की गई पंक्तियाँ और दूसरी तालिका की सभी पंक्तियाँ या, सभी तालिकाओं में सभी पंक्तियाँ (यह कोई फर्क नहीं पड़ता कि कोई मेल है या नहीं)।

तीन प्रकार के बाहरी जुड़ाव हैं:

२.१ लेफ्टिनेंट ओउर जोइन या लेफ्ट जॉइन

यह दायीं मेज से मेल खाती पंक्तियों के साथ बायीं मेज से सभी पंक्तियों को जोड़ देता है। यदि सही तालिका में कोई स्तंभ मेल नहीं खाते हैं, तो यह NULLमान लौटाता है।

२.२ राइट ओमर जॉय या राइट जॉय

यह JOINबाईं तालिका से मिलान पंक्तियों के साथ दाईं तालिका से सभी पंक्तियों को लौटाता है। यदि बाईं तालिका में कोई स्तंभ मेल नहीं खाते हैं, तो यह NULLमान लौटाता है।

२.३ पूर्ण पूर्ण जॉय या पूर्ण जॉय

यह JOINजोड़ती है LEFT OUTER JOINऔरRIGHT OUTER JOIN । जब शर्तों को पूरा किया जाता है तो यह किसी भी तालिका से पंक्तियाँ लौटाता है और NULLजब कोई मिलान नहीं होता है तो मूल्य वापस कर देता है।

दूसरे शब्दों में, OUTER JOINइस तथ्य पर आधारित है कि: केवल एक तालिकाओं (सही या बाएँ) या तालिकाओं की तालिका (पूर्ण) में सूचीबद्ध प्रविष्टियों को सूचीबद्ध किया जाना चाहिए।

Note that `OUTER JOIN` is a loosened form of `INNER JOIN`.

3. प्राकृतिक जोइन:

यह दो स्थितियों पर आधारित है:

  1. JOINसमानता के लिए एक ही नाम के साथ सभी स्तंभों पर किया जाता है।
  2. परिणाम से डुप्लिकेट कॉलम निकालता है।

यह प्रकृति में अधिक सैद्धांतिक लगता है और इसके परिणामस्वरूप (शायद) अधिकांश DBMS भी इसका समर्थन करने से बाज नहीं आते हैं।

4. क्रॉस जॉइन:

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

5. चयन करें:

यह का एक अलग रूप नहीं है JOIN, बल्कि यह एक है JOIN( INNER, OUTERखुद के लिए एक तालिका के, आदि)।

संचालकों पर आधारित जॉइन

JOINक्लॉज के लिए उपयोग किए जाने वाले ऑपरेटर के आधार पर , दो प्रकार के JOINएस हो सकते हैं । वो हैं

  1. समान जोइन
  2. थीटा जोइन

1. समान जोइन:

जो भी JOINप्रकार ( INNER, OUTERआदि) के लिए, यदि हम केवल समानता ऑपरेटर (=) का उपयोग करते हैं, तो हम कहते हैं कि JOINएक हैEQUI JOIN

2. थीटा जॉइन:

यह वैसा ही है, EQUI JOINलेकिन यह अन्य सभी ऑपरेटरों जैसे>, <,> = आदि की अनुमति देता है।

बहुत से EQUI JOINऔर थीटा दोनों JOINको समान मानते हैं INNER, OUTER आदि JOIN। लेकिन मैं दृढ़ता से मानता हूं कि यह एक गलती है और विचारों को अस्पष्ट बनाता है। क्योंकि INNER JOIN, OUTER JOINआदि सभी तालिकाओं और उनके डेटा के साथ जुड़े हुए हैं जबकि EQUI JOINऔरTHETA JOIN साथ जुड़े हुए हैं केवल उन ऑपरेटरों के साथ जुड़े हुए हैं जिन्हें हम पूर्व में उपयोग करते हैं।

फिर से, कई ऐसे हैं जो NATURAL JOINकिसी प्रकार की "अजीबोगरीब" के रूप में मानते हैं EQUI JOIN। वास्तव में, यह सच है, क्योंकि पहली शर्त के लिए मैंने उल्लेख किया है NATURAL JOIN। हालाँकि, हमें केवल NATURAL JOINअकेले एस को प्रतिबंधित करने की आवश्यकता नहीं है । INNER JOINs, OUTER JOINs आदि भी हो सकता EQUI JOINहै।


2
अपेक्षाकृत नए
लेटिन जरीन हैं

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

क्या आप कुछ उदाहरण प्रदान कर सकते हैं?
अवि

67

परिभाषा:


JOINS डेटा को क्वेरी करने का तरीका है जो एक साथ कई टेबल से एक साथ जुड़ता है।

JOINS के प्रकार:


RDBMS से संबंधित 5 प्रकार के योग हैं:

  • इक्वि-ज्वाइन: समानता की स्थिति के आधार पर दो तालिकाओं से सामान्य रिकॉर्ड को जोड़ती है। तकनीकी रूप से, एक तालिका की प्राथमिक कुंजी के मान और अन्य तालिका के विदेशी कुंजी मानों की तुलना करने के लिए समानता-ऑपरेटर (=) का उपयोग करके बनाया गया सम्मिलित करें, इसलिए परिणाम सेट में दोनों तालिकाओं से सामान्य (मिलान किए गए) रिकॉर्ड शामिल हैं। कार्यान्वयन के लिए INNER-JOIN देखें।

  • नेचुरल-ज्वाइन: यह इक्वी-जॉइन का वर्जन है, जिसमें सेलेक्ट ऑपरेशन डुप्लिकेट कॉलम को छोड़ देता है। कार्यान्वयन के लिए INNER-JOIN देखें

  • नॉन-इक्वि-ज्वाइन: यह इक्व-जॉइन का उल्टा है जहां ज्वाइनिंग कंडीशन समान ऑपरेटर (=) उदा। के अलावा अन्य का उपयोग करता है; =!, <=,> =,>, <या BETWEEN इत्यादि कार्यान्वयन के लिए INNER-JOIN देखें।

  • सेल्फ-ज्वाइन:: ज्वाइन करने का एक कस्टमाइज्ड व्यवहार जहां एक टेबल खुद के साथ संयुक्त हो; यह आमतौर पर सेल्फ-रेफरेंसिंग टेबल (या यूनरी रिलेशनशिप यूनिट) को क्वेरी करने के लिए आवश्यक है। कार्यान्वयन के लिए INNER-JOINs देखें।

  • कार्टेशियन उत्पाद: यह क्रॉस बिना किसी शर्त के दोनों तालिकाओं के सभी रिकॉर्ड को जोड़ती है। तकनीकी रूप से, यह WHERE-Clause के बिना किसी क्वेरी का परिणाम सेट लौटाता है।

SQL चिंता और उन्नति के अनुसार, 3 प्रकार के जोड़ होते हैं और सभी RDBMS जॉइन इन प्रकार के जॉन्स का उपयोग करके प्राप्त किए जा सकते हैं।

  1. INNER-JOIN: यह दो तालिकाओं से मेल खाती पंक्तियों को मिलाता है (या जोड़ता है)। मिलान तालिकाओं के सामान्य स्तंभों और उनके तुलनात्मक संचालन के आधार पर किया जाता है। यदि समानता आधारित स्थिति तब: EQUI-JOIN ने प्रदर्शन किया, अन्यथा गैर-EQUI-Join।

  2. बाहरी-शामिल हों: यह दो तालिकाओं से मेल खाती पंक्तियों को मिलाता है (या जोड़ती है) और NULL मानों के साथ बेजोड़ पंक्तियाँ। हालाँकि, बिना-मिलान वाली पंक्तियों के चयन को अनुकूलित किया जा सकता है, जैसे कि उप-प्रकारों द्वारा पहली तालिका या दूसरी तालिका से बेजोड़ पंक्ति का चयन करना: बायाँ OUTER JOIN और RIGHT OUTER JOIN।

    2.1। बाईं ओर का बाहरी जोड़ (उर्फ, LEFT-JOIN): रिटर्न ने दो तालिकाओं से पंक्तियों का मिलान किया और केवल LEFT तालिका (यानी, पहली तालिका) से बेजोड़ है।

    2.2। सही बाहरी जोइन (उर्फ, राइट-जोइन): रिटर्न दो तालिकाओं से पंक्तियों से मेल खाती है और केवल सही तालिका से बेजोड़ है।

    2.3। फुल ओटर जॉइन (उर्फ ओटीन जॉइन): दोनों टेबल से रिटर्न और बेजोड़ मिलान।

  3. क्रॉस-जोइन: यह ज्वाइन विलय / मिलाप नहीं करता है बल्कि यह कार्टेशियन उत्पाद करता है।

यहां छवि विवरण दर्ज करें नोट: स्व-जोइन को आवश्यकता के आधार पर INNER-JOIN, OUTER-JOIN और CROSS-JOIN द्वारा प्राप्त किया जा सकता है, लेकिन तालिका को अपने साथ जोड़ना होगा।

अधिक जानकारी के लिए:

उदाहरण:

1.1: INNER-JOIN: इक्वी-जॉइन कार्यान्वयन

SELECT  *
FROM Table1 A 
 INNER JOIN Table2 B ON A.<Primary-Key> =B.<Foreign-Key>;

1.2: INNER-JOIN: प्राकृतिक-जोइन कार्यान्वयन

Select A.*, B.Col1, B.Col2          --But no B.ForeignKeyColumn in Select
 FROM Table1 A
 INNER JOIN Table2 B On A.Pk = B.Fk;

1.3: INON-JOIN, NON-Equi-join कार्यान्वयन के साथ

Select *
 FROM Table1 A INNER JOIN Table2 B On A.Pk <= B.Fk;

1.4: SEL-JOIN के साथ INNER-JOIN

Select *
 FROM Table1 A1 INNER JOIN Table1 A2 On A1.Pk = A2.Fk;

२.१: ओमर जोइन (पूर्ण बाहरी जुड़ाव)

Select *
 FROM Table1 A FULL OUTER JOIN Table2 B On A.Pk = B.Fk;

२.२: छोड़ दिया

Select *
 FROM Table1 A LEFT OUTER JOIN Table2 B On A.Pk = B.Fk;

२.३: राइट जॉइन

Select *
 FROM Table1 A RIGHT OUTER JOIN Table2 B On A.Pk = B.Fk;

3.1: क्रॉस जॉइन

Select *
 FROM TableA CROSS JOIN TableB;

3.2: क्रॉस जॉइन-सेल्फ जॉय

Select *
 FROM Table1 A1 CROSS JOIN Table1 A2;

// या //

Select *
 FROM Table1 A1,Table1 A2;

लेबल "तालिका 1" और "तालिका 2" और नीचे दिए गए लेबल अनुचित हैं, वे intersect/ except/ के चित्र से हैं union; यहाँ हलकों पंक्तियों से लौट आए हैं leftऔर right join, के रूप में गिने लेबल का कहना है। AXB चित्र बकवास है। cross join= inner join on 1=1& पहले आरेख का एक विशेष मामला है।
4

यह उल्लेख के लायक है SQL-92 परिभाषित करता है UNION JOIN। अब SQL: 2003 में अप्रचलित हो गया।
इंपलर

40

दिलचस्प रूप से अधिकांश अन्य उत्तर इन दो समस्याओं से ग्रस्त हैं:

मैंने हाल ही में इस विषय पर एक लेख लिखा है: एसक्यूएल में जॉइन टेबल्स के लिए कई अलग-अलग तरीकों से एक संभवतः अपूर्ण, व्यापक गाइड , जिसे मैं यहां संक्षेप में बताऊंगा।

सबसे पहले और सबसे महत्वपूर्ण: JOINs कार्टेशियन उत्पाद हैं

यही कारण है कि वेन आरेख उन्हें गलत तरीके से समझाते हैं, क्योंकि एक जॉइन दोनों में शामिल तालिकाओं के बीच एक कार्टेशियन उत्पाद बनाता है । विकिपीडिया इसे अच्छी तरह दिखाता है:

यहां छवि विवरण दर्ज करें

कार्टेशियन उत्पादों के लिए SQL सिंटैक्स है CROSS JOIN। उदाहरण के लिए:

SELECT *

-- This just generates all the days in January 2017
FROM generate_series(
  '2017-01-01'::TIMESTAMP,
  '2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
  INTERVAL '1 day'
) AS days(day)

-- Here, we're combining all days with all departments
CROSS JOIN departments

जो एक तालिका से सभी पंक्तियों को दूसरी तालिका से सभी पंक्तियों के साथ जोड़ती है:

स्रोत:

+--------+   +------------+
| day    |   | department |
+--------+   +------------+
| Jan 01 |   | Dept 1     |
| Jan 02 |   | Dept 2     |
| ...    |   | Dept 3     |
| Jan 30 |   +------------+
| Jan 31 |
+--------+

परिणाम:

+--------+------------+
| day    | department |
+--------+------------+
| Jan 01 | Dept 1     |
| Jan 01 | Dept 2     |
| Jan 01 | Dept 3     |
| Jan 02 | Dept 1     |
| Jan 02 | Dept 2     |
| Jan 02 | Dept 3     |
| ...    | ...        |
| Jan 31 | Dept 1     |
| Jan 31 | Dept 2     |
| Jan 31 | Dept 3     |
+--------+------------+

यदि हम सिर्फ एक अल्पविराम से अलग की गई सूची लिखते हैं, तो हमें वही मिलेगा:

-- CROSS JOINing two tables:
SELECT * FROM table1, table2

INNER JOIN (थीटा-जोइन)

एक INNER JOINसिर्फ एक फ़िल्टर किया जाता है CROSS JOINजहां फ़िल्टर विधेय कहा जाता है Thetaसंबंधपरक बीजगणित में।

उदाहरण के लिए:

SELECT *

-- Same as before
FROM generate_series(
  '2017-01-01'::TIMESTAMP,
  '2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
  INTERVAL '1 day'
) AS days(day)

-- Now, exclude all days/departments combinations for
-- days before the department was created
JOIN departments AS d ON day >= d.created_at

ध्यान दें कि कीवर्ड INNERवैकल्पिक है (एमएस एक्सेस को छोड़कर)।

( परिणाम उदाहरण के लिए लेख देखें )

एक्की जॉय

Theta-JOIN की एक खास तरह की समान JOIN है, जिसका हम सबसे ज्यादा इस्तेमाल करते हैं। विधेय एक तालिका की प्राथमिक कुंजी को दूसरी तालिका की विदेशी कुंजी के साथ जोड़ता है। यदि हम चित्रण के लिए सकिला डेटाबेस का उपयोग करते हैं , तो हम लिख सकते हैं:

SELECT *
FROM actor AS a
JOIN film_actor AS fa ON a.actor_id = fa.actor_id
JOIN film AS f ON f.film_id = fa.film_id

यह सभी अभिनेताओं को उनकी फिल्मों के साथ जोड़ती है।

या कुछ डेटाबेस पर भी:

SELECT *
FROM actor
JOIN film_actor USING (actor_id)
JOIN film USING (film_id)

USING()वाक्य रचना एक स्तंभ के एक आपरेशन के टेबल में शामिल हों और उन दो स्तंभों पर एक समानता विधेय बनाता है कि दोनों तरफ से दिया जाना चाहिए निर्दिष्ट करने के लिए अनुमति देता है।

प्राकृतिक जोइन

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

यहाँ वाक्यविन्यास है:

SELECT *
FROM actor
NATURAL JOIN film_actor
NATURAL JOIN film

उमर जोइन

अब, OUTER JOINयह थोड़ा अलग है INNER JOINक्योंकि यह UNIONकई कार्टेसियन उत्पादों का निर्माण करता है। हम लिख सकते है:

-- Convenient syntax:
SELECT *
FROM a LEFT JOIN b ON <predicate>

-- Cumbersome, equivalent syntax:
SELECT a.*, b.*
FROM a JOIN b ON <predicate>
UNION ALL
SELECT a.*, NULL, NULL, ..., NULL
FROM a
WHERE NOT EXISTS (
  SELECT * FROM b WHERE <predicate>
)

कोई भी उत्तरार्द्ध लिखना नहीं चाहता है, इसलिए हम लिखते हैं OUTER JOIN(जो आमतौर पर डेटाबेस द्वारा बेहतर अनुकूलित होता है)।

जैसे INNER, OUTERयहाँ कीवर्ड वैकल्पिक है।

OUTER JOIN तीन स्वादों में आता है:

  • LEFT [ OUTER ] JOIN: JOINअभिव्यक्ति की बाईं तालिका को संघ में जोड़ा गया है जैसा कि ऊपर दिखाया गया है।
  • RIGHT [ OUTER ] JOIN: JOINअभिव्यक्ति की सही तालिका को संघ में जोड़ा गया है जैसा कि ऊपर दिखाया गया है।
  • FULL [ OUTER ] JOIN: JOINअभिव्यक्ति के दोनों तालिकाओं को संघ में जोड़ा गया है जैसा कि ऊपर दिखाया गया है।

इन सभी को कीवर्ड के USING()साथ या साथ जोड़ा जा सकता है NATURAL( मैंने NATURAL FULL JOINहाल ही में वास्तविक विश्व उपयोग-केस किया है )

वैकल्पिक वाक्य रचना

ओरेकल और एसक्यूएल सर्वर में कुछ ऐतिहासिक, हटाए गए OUTER JOINसिंटैक्स हैं , जो पहले से ही एसक्यूएल मानक के लिए एक सिंटैक्स का समर्थन करते हैं:

-- Oracle
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id = fa.actor_id(+)
AND fa.film_id = f.film_id(+)

-- SQL Server
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id *= fa.actor_id
AND fa.film_id *= f.film_id

ऐसा कहने के बाद, इस सिंटैक्स का उपयोग न करें। मैं इसे यहाँ सूचीबद्ध करता हूँ ताकि आप इसे पुराने ब्लॉग पोस्ट / विरासत कोड से पहचान सकें।

विभाजन OUTER JOIN

कुछ लोगों को यह पता है, लेकिन SQL मानक विभाजन को निर्दिष्ट करता है OUTER JOIN(और Oracle इसे लागू करता है)। आप इस तरह की बातें लिख सकते हैं:

WITH

  -- Using CONNECT BY to generate all dates in January
  days(day) AS (
    SELECT DATE '2017-01-01' + LEVEL - 1
    FROM dual
    CONNECT BY LEVEL <= 31
  ),

  -- Our departments
  departments(department, created_at) AS (
    SELECT 'Dept 1', DATE '2017-01-10' FROM dual UNION ALL
    SELECT 'Dept 2', DATE '2017-01-11' FROM dual UNION ALL
    SELECT 'Dept 3', DATE '2017-01-12' FROM dual UNION ALL
    SELECT 'Dept 4', DATE '2017-04-01' FROM dual UNION ALL
    SELECT 'Dept 5', DATE '2017-04-02' FROM dual
  )
SELECT *
FROM days 
LEFT JOIN departments 
  PARTITION BY (department) -- This is where the magic happens
  ON day >= created_at

परिणाम के कुछ हिस्सों:

+--------+------------+------------+
| day    | department | created_at |
+--------+------------+------------+
| Jan 01 | Dept 1     |            | -- Didn't match, but still get row
| Jan 02 | Dept 1     |            | -- Didn't match, but still get row
| ...    | Dept 1     |            | -- Didn't match, but still get row
| Jan 09 | Dept 1     |            | -- Didn't match, but still get row
| Jan 10 | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 11 | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 12 | Dept 1     | Jan 10     | -- Matches, so get join result
| ...    | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 31 | Dept 1     | Jan 10     | -- Matches, so get join result

यहाँ बिंदु यह है कि यदि JOINजॉइन के दूसरी तरफ कुछ भी मिलान किया जाता है, तो जॉइन्ट के विभाजन वाले हिस्से से सभी पंक्तियाँ परिणामी रूप से हवा देंगी । लंबी कहानी छोटी: यह रिपोर्टों में विरल डेटा भरना है। बहुत उपयोगी!

SEMI JOIN

गंभीरता से? कोई अन्य उत्तर नहीं मिला? बेशक, क्योंकि यह SQL में एक देशी वाक्यविन्यास नहीं है, दुर्भाग्य से (नीचे एएनटीआई की तरह)। लेकिन हम उपयोग कर सकते हैं IN()और EXISTS(), जैसे सभी अभिनेता जो फिल्मों में निभाई है खोजने के लिए:

SELECT *
FROM actor a
WHERE EXISTS (
  SELECT * FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)

WHERE a.actor_id = fa.actor_idके रूप में अर्द्ध विधेय में शामिल होने के विधेय कार्य करता है। यदि आप इसे नहीं मानते हैं, तो निष्पादन योजनाओं की जांच करें, जैसे कि ओरेकल। आप देखेंगे कि डेटाबेस एक SEMI JOIN ऑपरेशन को अंजाम देता है, EXISTS()विधेय को नहीं ।

यहां छवि विवरण दर्ज करें

ANTI जोइन

यह सिर्फ अर्ध के विपरीत है JOIN ( उपयोग करने के लिए नहीं सावधान रहना होगा NOT IN, हालांकि , के रूप में यह एक महत्वपूर्ण चेतावनी है)

यहाँ फिल्मों के बिना सभी कलाकार हैं:

SELECT *
FROM actor a
WHERE NOT EXISTS (
  SELECT * FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)

कुछ लोग (विशेष रूप से MySQL लोग) भी इस तरह से ANTI JOIN लिखते हैं:

SELECT *
FROM actor a
LEFT JOIN film_actor fa
USING (actor_id)
WHERE film_id IS NULL

मुझे लगता है कि ऐतिहासिक कारण प्रदर्शन है।

लेटेरियल जोइन

OMG, यह एक बहुत अच्छा है। मैं इसका उल्लेख करने वाला एकमात्र व्यक्ति हूं? यहाँ एक शांत प्रश्न है:

SELECT a.first_name, a.last_name, f.*
FROM actor AS a
LEFT OUTER JOIN LATERAL (
  SELECT f.title, SUM(amount) AS revenue
  FROM film AS f
  JOIN film_actor AS fa USING (film_id)
  JOIN inventory AS i USING (film_id)
  JOIN rental AS r USING (inventory_id)
  JOIN payment AS p USING (rental_id)
  WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!
  GROUP BY f.film_id
  ORDER BY revenue DESC
  LIMIT 5
) AS f
ON true

यह प्रति अभिनेता शीर्ष 5 राजस्व उत्पादक फिल्मों को मिलेगा। हर बार जब आपको TOP-N-per-something कुछ LATERAL JOINचाहिए होता है , तो वह आपका मित्र होगा। यदि आप एक SQL सर्वर व्यक्ति हैं, तो आप इस JOINप्रकार को नाम के तहत जानते हैंAPPLY

SELECT a.first_name, a.last_name, f.*
FROM actor AS a
OUTER APPLY (
  SELECT f.title, SUM(amount) AS revenue
  FROM film AS f
  JOIN film_actor AS fa ON f.film_id = fa.film_id
  JOIN inventory AS i ON f.film_id = i.film_id
  JOIN rental AS r ON i.inventory_id = r.inventory_id
  JOIN payment AS p ON r.rental_id = p.rental_id
  WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!
  GROUP BY f.film_id
  ORDER BY revenue DESC
  LIMIT 5
) AS f

ठीक है, शायद यह धोखा है, क्योंकि LATERAL JOINया एक APPLYअभिव्यक्ति वास्तव में एक "सहसंबद्ध सबक्वेरी" है जो कई पंक्तियों का उत्पादन करती है। लेकिन अगर हम "सहसंबद्ध उपश्रेणियों" के लिए अनुमति देते हैं, तो हम इसके बारे में भी बात कर सकते हैं ...

मल्टीसेट

यह केवल Oracle और Informix (मेरी जानकारी के लिए) द्वारा कार्यान्वित किया गया है, लेकिन इसे पोस्टग्रेएसक्यू में सरणियों और / या XML और XML का उपयोग करते हुए SQL सर्वर में उपयोग किया जा सकता है।

MULTISETएक सहसंबद्ध सबक्वेरी का उत्पादन करता है और बाहरी क्वेरी में पंक्तियों के परिणामस्वरूप सेट को घोंसला देता है। नीचे दी गई क्वेरी सभी अभिनेताओं का चयन करती है और प्रत्येक अभिनेता के लिए उनकी फिल्मों को एक नेस्टेड संग्रह में एकत्रित करता है:

SELECT a.*, MULTISET (
  SELECT f.*
  FROM film AS f
  JOIN film_actor AS fa USING (film_id)
  WHERE a.actor_id = fa.actor_id
) AS films
FROM actor

आप देखा है, वहाँ सिर्फ "बोरिंग" की तुलना में शामिल हों के अधिक प्रकार के होते हैं INNER, OUTERऔर CROSS JOINकि आम तौर पर उल्लेख कर रहे हैं। मेरे लेख में अधिक जानकारी । और कृपया, उन्हें चित्रित करने के लिए वेन आरेखों का उपयोग करना बंद करें।


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

@philipxy: विशिष्ट कुछ भी मुझे अपने उत्तर में बदलना चाहिए? आप एक संपादन का सुझाव दे सकते हैं ...
लुकास ईडर

10

मैंने एक दृष्टांत बनाया है जो शब्दों से बेहतर है, मेरी राय में: एसक्यूएल स्पष्टीकरण की तालिका में शामिल हों


@ नीरज सर्कल A & B में A & B की पंक्तियाँ नहीं हैं। वे बिना क्रेडिट के अन्यत्र से आँख बंद करके नकल करते हैं। क्रॉस जॉइन को इनर जॉइन केस में शामिल किया गया है, यह 1 = 1 पर इनर जॉइन है। किस तरह से चित्र "पूर्ण" के ये हिस्से हैं?
फिलीपिक्सी

@philipxy क्षमा करें, लेकिन मैं इसके बारे में परेशान नहीं हूं कि क्या यह कहीं और से कॉपी किया गया है। और मुझे यकीन नहीं है कि उपरोक्त तस्वीर में सही नहीं है। मेरे लिए यह ठीक है। क्रॉस जॉइन का वर्णन यहां नहीं किया गया है। यह एक आंतरिक
नीरज

-3

मैं अपने पालतू जानवर को धक्का देने जा रहा हूं: USING कीवर्ड।

यदि JOIN के दोनों किनारों पर दोनों विदेशी तालिकाओं के ठीक-ठीक नाम (यानी, एक ही नाम, केवल "id) नहीं हैं, तो इसे निम्न किया जा सकता है:

SELECT ...
FROM customers JOIN orders USING (customer_id)

मुझे यह बहुत व्यावहारिक, पठनीय लगता है, और अक्सर इसका उपयोग नहीं किया जाता है।


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