जॉइन (एसक्यूएल): Difference between revisions
No edit summary |
No edit summary |
||
Line 138: | Line 138: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<code>CROSS JOIN</code> सम्मिलित तालिका से पंक्तियों को फ़िल्टर करने के लिए स्वयं कोई | <code>CROSS JOIN</code> सम्मिलित तालिका से पंक्तियों को फ़िल्टर करने के लिए स्वयं कोई प्रेडिकेट प्रारम्भ नहीं करता है। ए के परिणाम <code>CROSS JOIN</code> के परिणामों को <code>WHERE</code> क्लॉज का उपयोग करके फ़िल्टर किया जा सकता है, जो तब इनर जॉइन के समतुल्य उत्पन्न कर सकता है। | ||
एसक्यूएल:2011 मानक में, क्रॉस जॉइन वैकल्पिक F401, एक्सटेंडेड जॉइन्ड टेबल, पैकेज का भाग हैं। | एसक्यूएल:2011 मानक में, क्रॉस जॉइन वैकल्पिक F401, एक्सटेंडेड जॉइन्ड टेबल, पैकेज का भाग हैं। | ||
Line 146: | Line 146: | ||
==इनर जॉइन== | ==इनर जॉइन== | ||
इनर जॉइन (या जॉइन) के लिए दो सम्मिलित तालिकाओं में प्रत्येक पंक्ति में युग्मित होने वाले कॉलम मानों की आवश्यकता होती है, और यह [[अनुप्रयोग प्रक्रिया सामग्री]] में सामान्यतः उपयोग किया जाने वाला जॉइन ऑपरेशन है, किन्तु इसे सभी स्थितियों में सबसे उत्तम विकल्प नहीं माना जाना चाहिए। इनर जॉइन, जॉइन-प्रेडिकेट के आधार पर दो तालिकाओं (ए और बी) के कॉलम मानों को सम्मिलित करके नई परिणाम तालिका बनाता है। क्वेरी ए की प्रत्येक पंक्ति की तुलना बी की प्रत्येक पंक्ति से करती है जिससे कि पंक्तियों के सभी जोड़े ज्ञात किये जा सकें जो जॉइन- | इनर जॉइन (या जॉइन) के लिए दो सम्मिलित तालिकाओं में प्रत्येक पंक्ति में युग्मित होने वाले कॉलम मानों की आवश्यकता होती है, और यह [[अनुप्रयोग प्रक्रिया सामग्री]] में सामान्यतः उपयोग किया जाने वाला जॉइन ऑपरेशन है, किन्तु इसे सभी स्थितियों में सबसे उत्तम विकल्प नहीं माना जाना चाहिए। इनर जॉइन, जॉइन-प्रेडिकेट के आधार पर दो तालिकाओं (ए और बी) के कॉलम मानों को सम्मिलित करके नई परिणाम तालिका बनाता है। क्वेरी ए की प्रत्येक पंक्ति की तुलना बी की प्रत्येक पंक्ति से करती है जिससे कि पंक्तियों के सभी जोड़े ज्ञात किये जा सकें जो जॉइन-प्रेडिकेट को संतुष्ट करते हैं। जब जॉइन-प्रेडिकेट गैर-[[ शून्य (एसक्यूएल) | शून्य]] मानों के मिलान से संतुष्ट होता है, तो ए और बी की पंक्तियों की प्रत्येक मिलान जोड़ी के लिए कॉलम मान परिणाम पंक्ति में संयोजित होते हैं। | ||
जॉइन के परिणाम को प्रथम तालिकाओं में सभी पंक्तियों के कार्टेशियन उत्पाद (या क्रॉस जॉइन) लेने के परिणाम के रूप में परिभाषित किया जा सकता है (तालिका ए में प्रत्येक पंक्ति को तालिका बी में प्रत्येक पंक्ति के साथ जोड़ना) और फिर सभी पंक्तियों को वापस करना जो जॉइन | जॉइन के परिणाम को प्रथम तालिकाओं में सभी पंक्तियों के कार्टेशियन उत्पाद (या क्रॉस जॉइन) लेने के परिणाम के रूप में परिभाषित किया जा सकता है (तालिका ए में प्रत्येक पंक्ति को तालिका बी में प्रत्येक पंक्ति के साथ जोड़ना) और फिर सभी पंक्तियों को वापस करना जो जॉइन प्रेडिकेट को संतुष्ट करते हैं। वास्तविक एसक्यूएल कार्यान्वयन सामान्यतः अन्य दृष्टिकोणों का उपयोग करते हैं, जैसे [[हैश जॉइन]] या [[सॉर्ट-मर्ज जॉइन]], क्योंकि कार्टेशियन उत्पाद की गणना धीमी है और स्टोर करने के लिए प्रायः बड़ी मात्रा में मेमोरी की आवश्यकता होती है। | ||
एसक्यूएल जॉइन को व्यक्त करने के लिए दो भिन्न-भिन्न वाक्यात्मक प्रकार निर्दिष्ट करता है: जो एक्सप्लिसिट जॉइन नोटेशन और इम्प्लिसिट जॉइन नोटेशन है। इम्प्लिसिट जॉइन नोटेशन को अब सर्वोत्तम अभ्यास नहीं माना जाता है{{By whom|date=September 2022}}, चूँकि डेटाबेस सिस्टम अभी भी इसका समर्थन करते हैं। | एसक्यूएल जॉइन को व्यक्त करने के लिए दो भिन्न-भिन्न वाक्यात्मक प्रकार निर्दिष्ट करता है: जो एक्सप्लिसिट जॉइन नोटेशन और इम्प्लिसिट जॉइन नोटेशन है। इम्प्लिसिट जॉइन नोटेशन को अब सर्वोत्तम अभ्यास नहीं माना जाता है{{By whom|date=September 2022}}, चूँकि डेटाबेस सिस्टम अभी भी इसका समर्थन करते हैं। | ||
Line 174: | Line 174: | ||
|| रैफर्टी || 31 || सेल्स | || रैफर्टी || 31 || सेल्स | ||
|} | |} | ||
इम्प्लिसिट जॉइन नोटेशन केवल <code>SELECT</code> कथन के <code>FROM</code> क्लॉज में सम्मिलित होने के लिए तालिकाओं को सूचीबद्ध करता है, और उन्हें अलग करने के लिए अल्पविराम का उपयोग करता है। इस प्रकार यह क्रॉस जॉइन निर्दिष्ट करता है, और <code>WHERE</code> क्लॉज अतिरिक्त फ़िल्टर-प्रेडिकेट प्रारम्भ कर सकता है (जो स्पष्ट नोटेशन में जॉइन-प्रेडिकेट की तुलना में कार्य करता है)। | |||
निम्नलिखित उदाहरण | निम्नलिखित उदाहरण पूर्व उदाहरण के समान है, किन्तु इस बार इम्प्लिसिट जॉइन नोटेशन का उपयोग किया जा रहा है: | ||
<syntaxhighlight lang=sql> | <syntaxhighlight lang=sql> | ||
Line 183: | Line 183: | ||
WHERE employee.DepartmentID = department.DepartmentID; | WHERE employee.DepartmentID = department.DepartmentID; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
ऊपर दिए गए उदाहरणों में दिए गए प्रश्न दोनों तालिकाओं के डिपार्टमेंटआईडी कॉलम का उपयोग करके | ऊपर दिए गए उदाहरणों में दिए गए प्रश्न दोनों तालिकाओं के डिपार्टमेंटआईडी कॉलम का उपयोग करके एम्प्लॉयी और डिपार्टमेंट तालिकाओं में सम्मिलित हो जाएंगे। जहां इन तालिकाओं का डिपार्टमेंटआईडी युग्मित होता है (अर्थात जॉइन-प्रेडिकेट संतुष्ट है), क्वेरी दो तालिकाओं से लास्टनेम, डिपार्टमेंटआईडी और डिपार्टमेंटनेम कॉलम को परिणाम पंक्ति में संयोजित करेगी। जहां डिपार्टमेंट आईडी युग्मित नहीं होती, और वहां कोई परिणाम पंक्ति उत्पन्न नहीं होती है। | ||
इस प्रकार उपरोक्त क्वेरी | इस प्रकार उपरोक्त क्वेरी के निष्पादन का परिणाम होगा: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 200: | Line 200: | ||
|| रैफर्टी || 31 || सेल्स | || रैफर्टी || 31 || सेल्स | ||
|} | |} | ||
एम्प्लॉयी विलियम्स और डिपार्टमेंट मार्केटिंग क्वेरी निष्पादन परिणामों में दिखाई नहीं देते हैं। इनमें से किसी की भी अन्य संबंधित तालिका में कोई युग्मित होने वाली पंक्तियाँ नहीं हैं: "विलियम्स" का कोई संबद्ध डिपार्टमेंट नहीं है, और किसी भी एम्प्लॉयी के पास डिपार्टमेंट आईडी 35 (मार्केटिंग) नहीं है। वांछित परिणामों के आधार पर, यह व्यवहार सूक्ष्म बग हो सकता है, जिसे इनर जॉइन को आउटर जॉइन से प्रतिस्थापित करके बचा जा सकता है। | |||
=== इनर जॉइन और शून्य मान === | === इनर जॉइन और शून्य मान === | ||
प्रोग्रामर को उन स्तंभों पर तालिकाओं को जोड़ते समय विशेष ध्यान रखना चाहिए जिनमें नल (एसक्यूएल) मान हो सकते हैं, क्योंकि NULL कभी भी किसी अन्य मान से मेल नहीं खाएगा (यहां तक कि NULL भी नहीं), जब तक कि जुड़ने की स्थिति स्पष्ट रूप से संयोजन | प्रोग्रामर को उन स्तंभों पर तालिकाओं को जोड़ते समय विशेष ध्यान रखना चाहिए जिनमें नल (एसक्यूएल) मान हो सकते हैं, क्योंकि NULL कभी भी किसी अन्य मान से मेल नहीं खाएगा (यहां तक कि NULL भी नहीं), जब तक कि जुड़ने की स्थिति स्पष्ट रूप से संयोजन प्रेडिकेट का उपयोग नहीं करती है जो पहले जांचता है कि कॉलम जुड़ते हैं हैं <code> NOT NULL</code> शेष प्रेडिकेट शर्त(शर्तों) को लागू करने से पहले। इनर जॉइन का उपयोग केवल उस डेटाबेस में सुरक्षित रूप से किया जा सकता है जो संदर्भात्मक अखंडता को लागू करता है या जहां जॉइन कॉलम के शून्य न होने की गारंटी होती है। कई लेनदेन प्रसंस्करण संबंधपरक डेटाबेस डेटा अखंडता सुनिश्चित करने के लिए ACID|परमाणुता, स्थिरता, अलगाव, स्थायित्व (ACID) डेटा अद्यतन मानकों पर भरोसा करते हैं, जिससे इनर जॉइन उपयुक्त विकल्प बन जाता है। हालाँकि, लेन-देन डेटाबेस में सामान्यतः वांछनीय जॉइन वाले कॉलम भी होते हैं जिन्हें NULL होने की अनुमति होती है। कई रिपोर्टिंग रिलेशनल डेटाबेस और [[डेटा वेयरहाउस]] हाई वॉल्यूम ्सट्रैक्ट, ट्रांसफॉर्म, लोड (ईटीएल) बैच अपडेट का उपयोग करते हैं जो संदर्भात्मक अखंडता को लागू करना मुश्किल या असंभव बनाते हैं, जिसके परिणामस्वरूप संभावित रूप से NULL जॉइन कॉलम होते हैं जिन्हें एसक्यूएल क्वेरी लेखक संशोधित नहीं कर सकता है और जो किसी त्रुटि के संकेत के बिना डेटा को छोड़ने के लिए इनर जॉइन का कारण बनता है। इनर जॉइन का उपयोग करने का विकल्प डेटाबेस डिज़ाइन और डेटा विशेषताओं पर निर्भर करता है। जब तालिका में सम्मिलित कॉलम में NULL मान हो सकते हैं, तो बाएं बाहरी जॉइन को सामान्यतः इनर जॉइन के लिए प्रतिस्थापित किया जा सकता है। | ||
कोई भी डेटा कॉलम जो NULL (खाली) हो सकता है, उसे कभी भी इनर जॉइन में लिंक के रूप में उपयोग नहीं किया जाना चाहिए, जब तक कि इच्छित परिणाम NULL मान वाली पंक्तियों को खत्म करना न हो। यदि [[परिणाम सेट]] से NULL जॉइन कॉलम को जानबूझकर हटाया जाना है, तो इनर जॉइन बाहरी जॉइन से तेज़ हो सकता है क्योंकि टेबल जॉइन और फ़िल्टरिंग ही चरण में की जाती है। इसके विपरीत, एसक्यूएल व्हेयर क्लॉज में डेटाबेस फ़ंक्शंस के साथ संयोजन में बड़ी मात्रा में क्वेरी में उपयोग किए जाने पर इनर जॉइन के परिणामस्वरूप विनाशकारी रूप से धीमा प्रदर्शन या सर्वर क्रैश भी हो सकता है।<ref>Greg Robidoux, "Avoid SQL Server functions in the WHERE clause for Performance", MSSQL Tips, 3 May 2007</ref><ref>Patrick Wolf, "Inside Oracle APEX "Caution when using PL/SQL functions in a SQL statement", 30 November 2006</ref><ref>Gregory A. Larsen, "T-SQL Best Practices - Don't Use Scalar Value Functions in Column List or WHERE Clauses", 29 October 2009,</ref> एसक्यूएल व्हेयर क्लॉज़ में फ़ंक्शन के परिणामस्वरूप डेटाबेस अपेक्षाकृत कॉम्पैक्ट टेबल इंडेक्स को अनदेखा कर सकता है। गणना किए गए मान पर निर्भर फ़िल्टर का उपयोग करके पंक्तियों की संख्या को कम करने से पहले डेटाबेस दोनों तालिकाओं से चयनित कॉलम को पढ़ और इनर रूप से जोड़ सकता है, जिसके परिणामस्वरूप अपेक्षाकृत भारी मात्रा में अकुशल प्रसंस्करण होता है। | कोई भी डेटा कॉलम जो NULL (खाली) हो सकता है, उसे कभी भी इनर जॉइन में लिंक के रूप में उपयोग नहीं किया जाना चाहिए, जब तक कि इच्छित परिणाम NULL मान वाली पंक्तियों को खत्म करना न हो। यदि [[परिणाम सेट]] से NULL जॉइन कॉलम को जानबूझकर हटाया जाना है, तो इनर जॉइन बाहरी जॉइन से तेज़ हो सकता है क्योंकि टेबल जॉइन और फ़िल्टरिंग ही चरण में की जाती है। इसके विपरीत, एसक्यूएल व्हेयर क्लॉज में डेटाबेस फ़ंक्शंस के साथ संयोजन में बड़ी मात्रा में क्वेरी में उपयोग किए जाने पर इनर जॉइन के परिणामस्वरूप विनाशकारी रूप से धीमा प्रदर्शन या सर्वर क्रैश भी हो सकता है।<ref>Greg Robidoux, "Avoid SQL Server functions in the WHERE clause for Performance", MSSQL Tips, 3 May 2007</ref><ref>Patrick Wolf, "Inside Oracle APEX "Caution when using PL/SQL functions in a SQL statement", 30 November 2006</ref><ref>Gregory A. Larsen, "T-SQL Best Practices - Don't Use Scalar Value Functions in Column List or WHERE Clauses", 29 October 2009,</ref> एसक्यूएल व्हेयर क्लॉज़ में फ़ंक्शन के परिणामस्वरूप डेटाबेस अपेक्षाकृत कॉम्पैक्ट टेबल इंडेक्स को अनदेखा कर सकता है। गणना किए गए मान पर निर्भर फ़िल्टर का उपयोग करके पंक्तियों की संख्या को कम करने से पहले डेटाबेस दोनों तालिकाओं से चयनित कॉलम को पढ़ और इनर रूप से जोड़ सकता है, जिसके परिणामस्वरूप अपेक्षाकृत भारी मात्रा में अकुशल प्रसंस्करण होता है। | ||
Line 233: | Line 233: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<code>USING</code> ई> निर्माण केवल वाक्यात्मक चीनी से अधिक है, हालांकि, परिणाम सेट स्पष्ट | <code>USING</code> ई> निर्माण केवल वाक्यात्मक चीनी से अधिक है, हालांकि, परिणाम सेट स्पष्ट प्रेडिकेट के साथ संस्करण के परिणाम सेट से भिन्न होता है। विशेष रूप से, में उल्लिखित कोई भी कॉलम <code>USING</code> सूची सम्मिलित होने वाली प्रत्येक तालिका के लिए बार के बजाय केवल बार अयोग्य नाम के साथ दिखाई देगी। उपरोक्त मामले में, ल होगा <code>DepartmentID</code> कॉलम और नं <code>employee.DepartmentID</code> या <code>department.DepartmentID</code>. <code>USING</code> e> क्लॉज MS एसक्यूएल सर्वर और Sybase द्वारा समर्थित नहीं है। | ||
====प्राकृतिक जॉइन==== | ====प्राकृतिक जॉइन==== | ||
Line 290: | Line 290: | ||
:<math>R \bowtie S = \left\{ t \cup s \mid t \in R \ \land \ s \in S \ \land \ \mathit{Fun}(t \cup s) \right\}</math>, | :<math>R \bowtie S = \left\{ t \cup s \mid t \in R \ \land \ s \in S \ \land \ \mathit{Fun}(t \cup s) \right\}</math>, | ||
जहां फन [[विधेय (गणित)]] है जो [[संबंध (गणित)]] आर के लिए सत्य है यदि और केवल यदि आर फ़ंक्शन है। सामान्यतः यह आवश्यक है कि आर और एस में कम से कम सामान्य विशेषता होनी चाहिए, किन्तु यदि इस बाधा को छोड़ दिया जाता है, और आर और एस में कोई सामान्य विशेषता नहीं है, तो प्राकृतिक जॉइन बिल्कुल कार्टेशियन उत्पाद बन जाता है। | जहां फन [[विधेय (गणित)|प्रेडिकेट (गणित)]] है जो [[संबंध (गणित)]] आर के लिए सत्य है यदि और केवल यदि आर फ़ंक्शन है। सामान्यतः यह आवश्यक है कि आर और एस में कम से कम सामान्य विशेषता होनी चाहिए, किन्तु यदि इस बाधा को छोड़ दिया जाता है, और आर और एस में कोई सामान्य विशेषता नहीं है, तो प्राकृतिक जॉइन बिल्कुल कार्टेशियन उत्पाद बन जाता है। | ||
प्राकृतिक जॉइन को कोडड के आदिमों के साथ निम्नानुसार अनुकरण किया जा सकता है। चलो सी<sub>1</sub>, ..., सी<sub>''m''</sub> आर और एस, आर के लिए सामान्य विशेषता नाम बनें<sub>1</sub>, ..., आर<sub>''n''</sub> आर और लेट एस के लिए अद्वितीय विशेषता नाम बनें<sub>1</sub>, ..., एस<sub>''k''</sub> एस के लिए अद्वितीय विशेषताएँ बनें। इसके अलावा, मान लें कि विशेषता नाम x है<sub>1</sub>, ..., ्स<sub>''m''</sub> न तो आर में हैं और न ही एस में। पहले चरण में अब एस में सामान्य विशेषता नामों का नाम बदला जा सकता है: | प्राकृतिक जॉइन को कोडड के आदिमों के साथ निम्नानुसार अनुकरण किया जा सकता है। चलो सी<sub>1</sub>, ..., सी<sub>''m''</sub> आर और एस, आर के लिए सामान्य विशेषता नाम बनें<sub>1</sub>, ..., आर<sub>''n''</sub> आर और लेट एस के लिए अद्वितीय विशेषता नाम बनें<sub>1</sub>, ..., एस<sub>''k''</sub> एस के लिए अद्वितीय विशेषताएँ बनें। इसके अलावा, मान लें कि विशेषता नाम x है<sub>1</sub>, ..., ्स<sub>''m''</sub> न तो आर में हैं और न ही एस में। पहले चरण में अब एस में सामान्य विशेषता नामों का नाम बदला जा सकता है: | ||
Line 298: | Line 298: | ||
:<math>U = \pi_{r_1,\ldots,r_n,c_1,\ldots,c_m,s_1,\ldots,s_k}(P)</math> | :<math>U = \pi_{r_1,\ldots,r_n,c_1,\ldots,c_m,s_1,\ldots,s_k}(P)</math> | ||
[[ प्राकृतिक जुड़ाव | प्राकृतिक जॉइन]] प्रकार का इक्वि-जॉइन है जहां जॉइन | [[ प्राकृतिक जुड़ाव | प्राकृतिक जॉइन]] प्रकार का इक्वि-जॉइन है जहां जॉइन प्रेडिकेट दोनों तालिकाओं में सभी कॉलमों की तुलना करके अंतर्निहित रूप से उत्पन्न होता है, जिसमें सम्मिलित तालिकाओं में समान कॉलम-नाम होते हैं। परिणामी सम्मिलित तालिका में समान रूप से नामित स्तंभों की प्रत्येक जोड़ी के लिए केवल स्तंभ होता है। ऐसी स्थिति में जब समान नाम वाला कोई कॉलम नहीं मिलता है, तो परिणाम [[क्रॉस जॉइन]] होता है। | ||
अधिकांश विशेषज्ञ इस बात से सहमत हैं कि प्राकृतिक जोड़ खतरनाक हैं और इसलिए उनके उपयोग को दृढ़ता से हतोत्साहित करते हैं।<ref>[http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:13430766143199 Ask Tom "Oracle support of ANSI joins."] [http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/#comment-2837 Back to basics: inner joins » Eddie Awad's Blog] {{Webarchive|url=https://web.archive.org/web/20101119182541/http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/#comment-2837 |date=2010-11-19 }}</ref> खतरा अनजाने में नया कॉलम जोड़ने से आता है, जिसका नाम दूसरी तालिका के दूसरे कॉलम के समान है। मौजूदा प्राकृतिक जोड़ स्वाभाविक रूप से तुलना के लिए नए कॉलम का उपयोग कर सकता है, पहले की तुलना में विभिन्न मानदंडों (विभिन्न कॉलमों से) का उपयोग करके तुलना/मिलान कर सकता है। इस प्रकार मौजूदा क्वेरी अलग-अलग परिणाम दे सकती है, भले ही तालिकाओं में डेटा बदला नहीं गया है, बल्कि केवल संवर्धित किया गया है। तालिका लिंक को स्वचालित रूप से निर्धारित करने के लिए कॉलम नामों का उपयोग सैकड़ों या हजारों तालिकाओं वाले बड़े डेटाबेस में विकल्प नहीं है, जहां यह नामकरण परंपराओं पर अवास्तविक बाधा डालेगा। वास्तविक दुनिया के डेटाबेस सामान्यतः विदेशी कुंजी डेटा के साथ डिज़ाइन किए जाते हैं जो व्यावसायिक नियमों और संदर्भ के कारण लगातार पॉप्युलेट नहीं होते हैं (शून्य मानों की अनुमति है)। विभिन्न तालिकाओं में समान डेटा के कॉलम नामों को संशोधित करना आम बात है और कठोर स्थिरता की यह कमी प्राकृतिक जॉइन को चर्चा के लिए सैद्धांतिक अवधारणा में बदल देती है। | अधिकांश विशेषज्ञ इस बात से सहमत हैं कि प्राकृतिक जोड़ खतरनाक हैं और इसलिए उनके उपयोग को दृढ़ता से हतोत्साहित करते हैं।<ref>[http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:13430766143199 Ask Tom "Oracle support of ANSI joins."] [http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/#comment-2837 Back to basics: inner joins » Eddie Awad's Blog] {{Webarchive|url=https://web.archive.org/web/20101119182541/http://awads.net/wp/2006/03/20/back-to-basics-inner-joins/#comment-2837 |date=2010-11-19 }}</ref> खतरा अनजाने में नया कॉलम जोड़ने से आता है, जिसका नाम दूसरी तालिका के दूसरे कॉलम के समान है। मौजूदा प्राकृतिक जोड़ स्वाभाविक रूप से तुलना के लिए नए कॉलम का उपयोग कर सकता है, पहले की तुलना में विभिन्न मानदंडों (विभिन्न कॉलमों से) का उपयोग करके तुलना/मिलान कर सकता है। इस प्रकार मौजूदा क्वेरी अलग-अलग परिणाम दे सकती है, भले ही तालिकाओं में डेटा बदला नहीं गया है, बल्कि केवल संवर्धित किया गया है। तालिका लिंक को स्वचालित रूप से निर्धारित करने के लिए कॉलम नामों का उपयोग सैकड़ों या हजारों तालिकाओं वाले बड़े डेटाबेस में विकल्प नहीं है, जहां यह नामकरण परंपराओं पर अवास्तविक बाधा डालेगा। वास्तविक दुनिया के डेटाबेस सामान्यतः विदेशी कुंजी डेटा के साथ डिज़ाइन किए जाते हैं जो व्यावसायिक नियमों और संदर्भ के कारण लगातार पॉप्युलेट नहीं होते हैं (शून्य मानों की अनुमति है)। विभिन्न तालिकाओं में समान डेटा के कॉलम नामों को संशोधित करना आम बात है और कठोर स्थिरता की यह कमी प्राकृतिक जॉइन को चर्चा के लिए सैद्धांतिक अवधारणा में बदल देती है। | ||
Line 333: | Line 333: | ||
===बायां बाहरी जॉइन=== | ===बायां बाहरी जॉइन=== | ||
तालिका ए और बी के लिए बाएं बाहरी जोड़ (या बस बाएं जोड़) के परिणाम में हमेशा बाईं तालिका (ए) की सभी पंक्तियां सम्मिलित होती हैं, भले ही सम्मिलित होने की स्थिति को सही तालिका (बी) में कोई मिलान पंक्ति नहीं मिलती है। इसका मतलब यह है कि यदि <code>ON</code> | तालिका ए और बी के लिए बाएं बाहरी जोड़ (या बस बाएं जोड़) के परिणाम में हमेशा बाईं तालिका (ए) की सभी पंक्तियां सम्मिलित होती हैं, भले ही सम्मिलित होने की स्थिति को सही तालिका (बी) में कोई मिलान पंक्ति नहीं मिलती है। इसका मतलब यह है कि यदि <code>ON</code> क्लॉज़ बी में 0 (शून्य) पंक्तियों से मेल खाता है (ए में दी गई पंक्ति के लिए), जॉइन अभी भी परिणाम में पंक्ति लौटाएगा (उस पंक्ति के लिए) - किन्तु बी से प्रत्येक कॉलम में शून्य के साथ। बायां बाहरी जॉइन सभी को लौटाता है इनर जॉइन के मान और बाईं तालिका के सभी मान जो दाहिनी तालिका से मेल नहीं खाते हैं, जिसमें लिंक कॉलम में NULL (खाली) मान वाली पंक्तियाँ भी सम्मिलित हैं। | ||
उदाहरण के लिए, यह हमें किसी कर्मचारी का विभाग ढूंढने की अनुमति देता है, किन्तु फिर भी उन कर्मचारियों को दिखाता है जिन्हें किसी विभाग को नहीं सौंपा गया है (ऊपर दिए गए इनर-जॉइन उदाहरण के विपरीत, जहां बिना असाइन किए गए कर्मचारियों को परिणाम से बाहर रखा गया था)। | उदाहरण के लिए, यह हमें किसी कर्मचारी का विभाग ढूंढने की अनुमति देता है, किन्तु फिर भी उन कर्मचारियों को दिखाता है जिन्हें किसी विभाग को नहीं सौंपा गया है (ऊपर दिए गए इनर-जॉइन उदाहरण के विपरीत, जहां बिना असाइन किए गए कर्मचारियों को परिणाम से बाहर रखा गया था)। | ||
Line 585: | Line 585: | ||
[[Image:Comparison of join algorithms.png|thumb|सबसे खराब स्थिति वाले इष्टतम एल्गोरिदम जैसे कि जेनेरिक जॉइन समय में ही विशेषता पर काम करते हैं किन्तु इस विशेषता पर सभी संबंधों को जोड़ते हैं।<ref>{{Cite arXiv |last1=Wang |first1=Yisu Remy |last2=Willsey |first2=Max |last3=Suciu |first3=Dan |date=2023-01-27 |title=Free Join: Unifying Worst-Case Optimal and Traditional Joins |class=cs.DB |eprint=2301.10841 }}</ref>]]बाइनरी जॉइन ऑपरेशन करने के लिए तीन मौलिक एल्गोरिदम मौजूद हैं: [[नेस्टेड लूप जॉइन]], सॉर्ट-मर्ज जॉइन और हैश जॉइन। सबसे खराब स्थिति में इष्टतम जॉइन एल्गोरिदम, सबसे खराब स्थिति में दो से अधिक संबंधों के बीच जुड़ने के लिए बाइनरी जॉइन एल्गोरिदम की तुलना में एसिम्प्टोटिक रूप से तेज़ हैं। | [[Image:Comparison of join algorithms.png|thumb|सबसे खराब स्थिति वाले इष्टतम एल्गोरिदम जैसे कि जेनेरिक जॉइन समय में ही विशेषता पर काम करते हैं किन्तु इस विशेषता पर सभी संबंधों को जोड़ते हैं।<ref>{{Cite arXiv |last1=Wang |first1=Yisu Remy |last2=Willsey |first2=Max |last3=Suciu |first3=Dan |date=2023-01-27 |title=Free Join: Unifying Worst-Case Optimal and Traditional Joins |class=cs.DB |eprint=2301.10841 }}</ref>]]बाइनरी जॉइन ऑपरेशन करने के लिए तीन मौलिक एल्गोरिदम मौजूद हैं: [[नेस्टेड लूप जॉइन]], सॉर्ट-मर्ज जॉइन और हैश जॉइन। सबसे खराब स्थिति में इष्टतम जॉइन एल्गोरिदम, सबसे खराब स्थिति में दो से अधिक संबंधों के बीच जुड़ने के लिए बाइनरी जॉइन एल्गोरिदम की तुलना में एसिम्प्टोटिक रूप से तेज़ हैं। | ||
=== | ===जॉइन इन्डेक्सेस === | ||
जॉइन इंडेक्स [[ डेटाबेस सूचकांक ]] हैं जो डेटा वेयरहाउस में जॉइन क्वेरी के प्रसंस्करण की सुविधा प्रदान करते हैं: वे वर्तमान में (2012) [[ओरेकल डेटाबेस]] द्वारा कार्यान्वयन में उपलब्ध हैं<ref>Oracle Bitmap Join Index. URL: http://www.dba-oracle.com/art_builder_bitmap_join_idx.htm</ref> और [[टेराडाटा]].<ref>Teradata Join Indexes. {{cite web|url=http://www.coffingdw.com/sql/tdsqlutp/join_index.htm |title=Join Index |access-date=2012-06-14 |url-status=dead |archive-url=https://web.archive.org/web/20121216123745/http://www.coffingdw.com/sql/tdsqlutp/join_index.htm |archive-date=2012-12-16 }}</ref> | जॉइन इंडेक्स [[ डेटाबेस सूचकांक |डेटाबेस सूचकांक]] हैं जो डेटा वेयरहाउस में जॉइन क्वेरी के प्रसंस्करण की सुविधा प्रदान करते हैं: वे वर्तमान में (2012) [[ओरेकल डेटाबेस]] द्वारा कार्यान्वयन में उपलब्ध हैं<ref>Oracle Bitmap Join Index. URL: http://www.dba-oracle.com/art_builder_bitmap_join_idx.htm</ref> और [[टेराडाटा]].<ref>Teradata Join Indexes. {{cite web|url=http://www.coffingdw.com/sql/tdsqlutp/join_index.htm |title=Join Index |access-date=2012-06-14 |url-status=dead |archive-url=https://web.archive.org/web/20121216123745/http://www.coffingdw.com/sql/tdsqlutp/join_index.htm |archive-date=2012-12-16 }}</ref> | ||
टेराडाटा कार्यान्वयन में, निर्दिष्ट कॉलम, कॉलम पर समग्र कार्य, या या अधिक तालिकाओं से दिनांक कॉलम के घटकों को [[डेटाबेस दृश्य]] की परिभाषा के समान सिंटैक्स का उपयोग करके निर्दिष्ट किया जाता है: 64 कॉलम/कॉलम अभिव्यक्तियों को ल में निर्दिष्ट किया जा सकता है सूचकांक में सम्मिलित हों. वैकल्पिक रूप से, कॉलम जो समग्र डेटा की प्राथमिक कुंजी को परिभाषित करता है, उसे भी निर्दिष्ट किया जा सकता है: समानांतर हार्डवेयर पर, कॉलम मानों का उपयोग सूचकांक की सामग्री को कई डिस्क में विभाजित करने के लिए किया जाता है। जब स्रोत तालिकाओं को उपयोगकर्ताओं द्वारा इंटरैक्टिव रूप से अपडेट किया जाता है, तो जॉइन इंडेक्स की सामग्री स्वचालित रूप से अपडेट हो जाती है। कोई भी क्वेरी जिसका [[ कहां (एसक्यूएल) ]] कॉलम या कॉलम ्सप्रेशन के किसी भी संयोजन को निर्दिष्ट करता है जो कि जॉइन इंडेक्स (तथाकथित कवरिंग क्वेरी) में परिभाषित लोगों का सटीक सबसेट है, मूल तालिकाओं और उनके इंडेक्स के बजाय जॉइन इंडेक्स का कारण बनेगा, क्वेरी निष्पादन के दौरान परामर्श लिया जाना। | टेराडाटा कार्यान्वयन में, निर्दिष्ट कॉलम, कॉलम पर समग्र कार्य, या या अधिक तालिकाओं से दिनांक कॉलम के घटकों को [[डेटाबेस दृश्य]] की परिभाषा के समान सिंटैक्स का उपयोग करके निर्दिष्ट किया जाता है: 64 कॉलम/कॉलम अभिव्यक्तियों को ल में निर्दिष्ट किया जा सकता है सूचकांक में सम्मिलित हों. वैकल्पिक रूप से, कॉलम जो समग्र डेटा की प्राथमिक कुंजी को परिभाषित करता है, उसे भी निर्दिष्ट किया जा सकता है: समानांतर हार्डवेयर पर, कॉलम मानों का उपयोग सूचकांक की सामग्री को कई डिस्क में विभाजित करने के लिए किया जाता है। जब स्रोत तालिकाओं को उपयोगकर्ताओं द्वारा इंटरैक्टिव रूप से अपडेट किया जाता है, तो जॉइन इंडेक्स की सामग्री स्वचालित रूप से अपडेट हो जाती है। कोई भी क्वेरी जिसका [[ कहां (एसक्यूएल) ]] कॉलम या कॉलम ्सप्रेशन के किसी भी संयोजन को निर्दिष्ट करता है जो कि जॉइन इंडेक्स (तथाकथित कवरिंग क्वेरी) में परिभाषित लोगों का सटीक सबसेट है, मूल तालिकाओं और उनके इंडेक्स के बजाय जॉइन इंडेक्स का कारण बनेगा, क्वेरी निष्पादन के दौरान परामर्श लिया जाना। | ||
Line 593: | Line 593: | ||
टेराडेटा के लिए, ओरेकल बिटमैप जॉइन इंडेक्स का उपयोग केवल प्रश्न का उत्तर देने के लिए किया जाता है जब क्वेरी का व्हेयर (एसक्यूएल) उन कॉलमों तक सीमित होता है जो जॉइन इंडेक्स में सम्मिलित होते हैं। | टेराडेटा के लिए, ओरेकल बिटमैप जॉइन इंडेक्स का उपयोग केवल प्रश्न का उत्तर देने के लिए किया जाता है जब क्वेरी का व्हेयर (एसक्यूएल) उन कॉलमों तक सीमित होता है जो जॉइन इंडेक्स में सम्मिलित होते हैं। | ||
=== | === स्ट्रैट जॉइन === | ||
कुछ डेटाबेस सिस्टम उपयोगकर्ता को सिस्टम को विशेष क्रम में तालिकाओं को पढ़ने के लिए बाध्य करने की अनुमति देते हैं। इसका उपयोग तब किया जाता है जब जॉइन ऑप्टिमाइज़र तालिकाओं को अकुशल क्रम में पढ़ने का विकल्प चयन किया जाता है। उदाहरण के लिए, [[MySQL|My]]एसक्यूएल में कमांड <code>STRAIGHT_JOIN</code> तालिकाओं को क्वेरी में सूचीबद्ध क्रम में ही पढ़ता है।<ref>{{Cite web|title = 13.2.9.2 JOIN Syntax|url = https://dev.mysql.com/doc/refman/5.7/en/join.html|website = MySQL 5.7 Reference Manual|access-date = 2015-12-03|publisher = [[Oracle Corporation]]}}</ref> | कुछ डेटाबेस सिस्टम उपयोगकर्ता को सिस्टम को विशेष क्रम में तालिकाओं को पढ़ने के लिए बाध्य करने की अनुमति देते हैं। इसका उपयोग तब किया जाता है जब जॉइन ऑप्टिमाइज़र तालिकाओं को अकुशल क्रम में पढ़ने का विकल्प चयन किया जाता है। उदाहरण के लिए, [[MySQL|My]]एसक्यूएल में कमांड <code>STRAIGHT_JOIN</code> तालिकाओं को क्वेरी में सूचीबद्ध क्रम में ही पढ़ता है।<ref>{{Cite web|title = 13.2.9.2 JOIN Syntax|url = https://dev.mysql.com/doc/refman/5.7/en/join.html|website = MySQL 5.7 Reference Manual|access-date = 2015-12-03|publisher = [[Oracle Corporation]]}}</ref> | ||
Revision as of 10:25, 4 August 2023
स्ट्रक्चर्ड क्वेरी लैंग्वेज (एसक्यूएल) में जॉइन क्लॉज एक या अधिक टेबल के कॉलम को नई टेबल में जोड़ता है। यह ऑपरेशन संबंधपरक बीजगणित में जॉइन ऑपरेशन से युग्मित होता है। अनौपचारिक रूप से, जोड़ दो तालिकाओं को जोड़ता है और युग्मित होने वाली फ़ील्ड के साथ एक ही पंक्ति में रिकॉर्ड रखता है: INNER
, LEFT OUTER
, RIGHT OUTER
, FULL OUTER
और CROSS
आदि।
उदाहरण तालिकाएँ
जॉइन प्रकारों को समझाने के लिए, इस आलेख का शेष भाग निम्नलिखित तालिकाओं का उपयोग करता है:
लास्टनेम | डिपार्टमेंटआईडी |
---|---|
रैफर्टी | 31 |
जोन्स | 33 |
हाइजेनबर्ग | 33 |
रॉबिंसन | 34 |
स्मिथ | 34 |
विलियम्स | NULL
|
डिपार्टमेंटआईडी | डिपार्टमेंटनेम |
---|---|
31 | सेल्स |
33 | इंजीनियरिंग |
34 | क्लेरिकल |
35 | मार्केटिंग |
Department.DepartmentID
Department
टेबल की प्राथमिक कुंजी है, जबकि Employee.DepartmentID
विदेशी कुंजी है।
ध्यान दें कि Employee
में, विलियम्स को अभी तक कोई डिपार्टमेंट नहीं दिया गया है। इसके अतिरिक्त, मार्केटिंग डिपार्टमेंट में किसी भी एम्प्लॉयी को नियुक्त नहीं किया गया है।
उपरोक्त तालिकाएँ बनाने के लिए ये एसक्यूएल कथन हैं:
<सिंटैक्सहाइलाइट लैंग= एसक्यूएल लाइन= 1 > टेबल विभाग बनाएं(
डिपार्टमेंटआईडी इंट प्राथमिक कुंजी शून्य नहीं है, विभाग का नाम VARCHAR(20)
);
टेबल कर्मचारी बनाएं (
अंतिम नाम VARCHAR(20), DepartmentID पूर्ण संदर्भ विभाग(DepartmentID)
);
विभाग में सम्मिलित करें मान (31, 'बिक्री'),
(33, 'इंजीनियरिंग'), (34, 'लिपिकीय'), (35, 'मार्केटिंग');
कर्मचारी में डालें मूल्य ('रैफर्टी', 31),
('जोन्स', 33), ('हाइजेनबर्ग', 33), ('रॉबिन्सन', 34), ('स्मिथ', 34), ('विलियम्स', शून्य);
</सिंटैक्सहाइलाइट>
क्रॉस जॉइन
CROSS JOIN
जॉइन में तालिकाओं से पंक्तियों का कार्टेशियन उत्पाद लौटाता है। दूसरे शब्दों में, यह ऐसी पंक्तियाँ उत्पन्न करेगा जो प्रथम तालिका की प्रत्येक पंक्ति को दूसरी तालिका की प्रत्येक पंक्ति के साथ जोड़ती हैं।[1]
एम्प्लॉयी लास्टनेम | एम्प्लॉयी डिपार्टमेंटआईडी | डिपार्टमेंट डिपार्टमेंटनेम | डिपार्टमेंट डिपार्टमेंटआईडी |
---|---|---|---|
रैफर्टी | 31 | सेल्स | 31 |
जोन्स | 33 | सेल्स | 31 |
हाइजेनबर्ग | 33 | सेल्स | 31 |
स्मिथ | 34 | सेल्स | 31 |
रॉबिंसन | 34 | सेल्स | 31 |
विलियम्स | NULL |
सेल्स | 31 |
रैफर्टी | 31 | इंजीनियरिंग | 33 |
जोन्स | 33 | इंजीनियरिंग | 33 |
हाइजेनबर्ग | 33 | इंजीनियरिंग | 33 |
स्मिथ | 34 | इंजीनियरिंग | 33 |
रॉबिंसन | 34 | इंजीनियरिंग | 33 |
विलियम्स | NULL |
इंजीनियरिंग | 33 |
रैफर्टी | 31 | क्लेरिकल | 34 |
जोन्स | 33 | क्लेरिकल | 34 |
हाइजेनबर्ग | 33 | क्लेरिकल | 34 |
स्मिथ | 34 | क्लेरिकल | 34 |
रॉबिंसन | 34 | क्लेरिकल | 34 |
विलियम्स | NULL |
क्लेरिकल | 34 |
रैफर्टी | 31 | मार्केटिंग | 35 |
जोन्स | 33 | मार्केटिंग | 35 |
हाइजेनबर्ग | 33 | मार्केटिंग | 35 |
स्मिथ | 34 | मार्केटिंग | 35 |
रॉबिंसन | 34 | मार्केटिंग | 35 |
विलियम्स | NULL |
मार्केटिंग | 35 |
स्पष्ट क्रॉस जॉइन का उदाहरण है:
SELECT *
FROM employee CROSS JOIN department;
अंतर्निहित क्रॉस जॉइन का उदाहरण है:
SELECT *
FROM employee, department;
क्रॉस जॉइन को सदैव उचित स्थिति के साथ इनर जॉइन से परिवर्तित किया जा सकता है:
SELECT *
FROM employee INNER JOIN department ON 1=1;
CROSS JOIN
सम्मिलित तालिका से पंक्तियों को फ़िल्टर करने के लिए स्वयं कोई प्रेडिकेट प्रारम्भ नहीं करता है। ए के परिणाम CROSS JOIN
के परिणामों को WHERE
क्लॉज का उपयोग करके फ़िल्टर किया जा सकता है, जो तब इनर जॉइन के समतुल्य उत्पन्न कर सकता है।
एसक्यूएल:2011 मानक में, क्रॉस जॉइन वैकल्पिक F401, एक्सटेंडेड जॉइन्ड टेबल, पैकेज का भाग हैं।
सामान्य उपयोग सर्वर के प्रदर्शन के परीक्षण के लिए होता है।[why?]
इनर जॉइन
इनर जॉइन (या जॉइन) के लिए दो सम्मिलित तालिकाओं में प्रत्येक पंक्ति में युग्मित होने वाले कॉलम मानों की आवश्यकता होती है, और यह अनुप्रयोग प्रक्रिया सामग्री में सामान्यतः उपयोग किया जाने वाला जॉइन ऑपरेशन है, किन्तु इसे सभी स्थितियों में सबसे उत्तम विकल्प नहीं माना जाना चाहिए। इनर जॉइन, जॉइन-प्रेडिकेट के आधार पर दो तालिकाओं (ए और बी) के कॉलम मानों को सम्मिलित करके नई परिणाम तालिका बनाता है। क्वेरी ए की प्रत्येक पंक्ति की तुलना बी की प्रत्येक पंक्ति से करती है जिससे कि पंक्तियों के सभी जोड़े ज्ञात किये जा सकें जो जॉइन-प्रेडिकेट को संतुष्ट करते हैं। जब जॉइन-प्रेडिकेट गैर- शून्य मानों के मिलान से संतुष्ट होता है, तो ए और बी की पंक्तियों की प्रत्येक मिलान जोड़ी के लिए कॉलम मान परिणाम पंक्ति में संयोजित होते हैं।
जॉइन के परिणाम को प्रथम तालिकाओं में सभी पंक्तियों के कार्टेशियन उत्पाद (या क्रॉस जॉइन) लेने के परिणाम के रूप में परिभाषित किया जा सकता है (तालिका ए में प्रत्येक पंक्ति को तालिका बी में प्रत्येक पंक्ति के साथ जोड़ना) और फिर सभी पंक्तियों को वापस करना जो जॉइन प्रेडिकेट को संतुष्ट करते हैं। वास्तविक एसक्यूएल कार्यान्वयन सामान्यतः अन्य दृष्टिकोणों का उपयोग करते हैं, जैसे हैश जॉइन या सॉर्ट-मर्ज जॉइन, क्योंकि कार्टेशियन उत्पाद की गणना धीमी है और स्टोर करने के लिए प्रायः बड़ी मात्रा में मेमोरी की आवश्यकता होती है।
एसक्यूएल जॉइन को व्यक्त करने के लिए दो भिन्न-भिन्न वाक्यात्मक प्रकार निर्दिष्ट करता है: जो एक्सप्लिसिट जॉइन नोटेशन और इम्प्लिसिट जॉइन नोटेशन है। इम्प्लिसिट जॉइन नोटेशन को अब सर्वोत्तम अभ्यास नहीं माना जाता है[by whom?], चूँकि डेटाबेस सिस्टम अभी भी इसका समर्थन करते हैं।
एक्सप्लिसिट जॉइन नोटेशन सम्मिलित होने के लिए तालिका निर्दिष्ट करने के लिए वैकल्पिक रूप से INNER
कीवर्ड से पूर्व JOIN
कीवर्ड का उपयोग करता है, और सम्मिलित होने के लिए पूर्वानुमान निर्दिष्ट करने के लिए ON
कीवर्ड का उपयोग करता है, जैसा कि निम्नलिखित उदाहरण में है:
SELECT employee.LastName, employee.DepartmentID, department.DepartmentName
FROM employee
INNER JOIN department ON
employee.DepartmentID = department.DepartmentID;
एम्प्लॉयी लास्टनेम | एम्प्लॉयी डिपार्टमेंटआईडी | डिपार्टमेंट डिपार्टमेंटनेम |
---|---|---|
रॉबिंसन | 34 | क्लेरिकल |
जोन्स | 33 | इंजीनियरिंग |
स्मिथ | 34 | क्लेरिकल |
हाइजेनबर्ग | 33 | इंजीनियरिंग |
रैफर्टी | 31 | सेल्स |
इम्प्लिसिट जॉइन नोटेशन केवल SELECT
कथन के FROM
क्लॉज में सम्मिलित होने के लिए तालिकाओं को सूचीबद्ध करता है, और उन्हें अलग करने के लिए अल्पविराम का उपयोग करता है। इस प्रकार यह क्रॉस जॉइन निर्दिष्ट करता है, और WHERE
क्लॉज अतिरिक्त फ़िल्टर-प्रेडिकेट प्रारम्भ कर सकता है (जो स्पष्ट नोटेशन में जॉइन-प्रेडिकेट की तुलना में कार्य करता है)।
निम्नलिखित उदाहरण पूर्व उदाहरण के समान है, किन्तु इस बार इम्प्लिसिट जॉइन नोटेशन का उपयोग किया जा रहा है:
SELECT employee.LastName, employee.DepartmentID, department.DepartmentName
FROM employee, department
WHERE employee.DepartmentID = department.DepartmentID;
ऊपर दिए गए उदाहरणों में दिए गए प्रश्न दोनों तालिकाओं के डिपार्टमेंटआईडी कॉलम का उपयोग करके एम्प्लॉयी और डिपार्टमेंट तालिकाओं में सम्मिलित हो जाएंगे। जहां इन तालिकाओं का डिपार्टमेंटआईडी युग्मित होता है (अर्थात जॉइन-प्रेडिकेट संतुष्ट है), क्वेरी दो तालिकाओं से लास्टनेम, डिपार्टमेंटआईडी और डिपार्टमेंटनेम कॉलम को परिणाम पंक्ति में संयोजित करेगी। जहां डिपार्टमेंट आईडी युग्मित नहीं होती, और वहां कोई परिणाम पंक्ति उत्पन्न नहीं होती है।
इस प्रकार उपरोक्त क्वेरी के निष्पादन का परिणाम होगा:
एम्प्लॉयी लास्टनेम | एम्प्लॉयी डिपार्टमेंटआईडी | डिपार्टमेंट डिपार्टमेंटनेम |
---|---|---|
रॉबिंसन | 34 | क्लेरिकल |
जोन्स | 33 | इंजीनियरिंग |
स्मिथ | 34 | क्लेरिकल |
हाइजेनबर्ग | 33 | इंजीनियरिंग |
रैफर्टी | 31 | सेल्स |
एम्प्लॉयी विलियम्स और डिपार्टमेंट मार्केटिंग क्वेरी निष्पादन परिणामों में दिखाई नहीं देते हैं। इनमें से किसी की भी अन्य संबंधित तालिका में कोई युग्मित होने वाली पंक्तियाँ नहीं हैं: "विलियम्स" का कोई संबद्ध डिपार्टमेंट नहीं है, और किसी भी एम्प्लॉयी के पास डिपार्टमेंट आईडी 35 (मार्केटिंग) नहीं है। वांछित परिणामों के आधार पर, यह व्यवहार सूक्ष्म बग हो सकता है, जिसे इनर जॉइन को आउटर जॉइन से प्रतिस्थापित करके बचा जा सकता है।
इनर जॉइन और शून्य मान
प्रोग्रामर को उन स्तंभों पर तालिकाओं को जोड़ते समय विशेष ध्यान रखना चाहिए जिनमें नल (एसक्यूएल) मान हो सकते हैं, क्योंकि NULL कभी भी किसी अन्य मान से मेल नहीं खाएगा (यहां तक कि NULL भी नहीं), जब तक कि जुड़ने की स्थिति स्पष्ट रूप से संयोजन प्रेडिकेट का उपयोग नहीं करती है जो पहले जांचता है कि कॉलम जुड़ते हैं हैं NOT NULL
शेष प्रेडिकेट शर्त(शर्तों) को लागू करने से पहले। इनर जॉइन का उपयोग केवल उस डेटाबेस में सुरक्षित रूप से किया जा सकता है जो संदर्भात्मक अखंडता को लागू करता है या जहां जॉइन कॉलम के शून्य न होने की गारंटी होती है। कई लेनदेन प्रसंस्करण संबंधपरक डेटाबेस डेटा अखंडता सुनिश्चित करने के लिए ACID|परमाणुता, स्थिरता, अलगाव, स्थायित्व (ACID) डेटा अद्यतन मानकों पर भरोसा करते हैं, जिससे इनर जॉइन उपयुक्त विकल्प बन जाता है। हालाँकि, लेन-देन डेटाबेस में सामान्यतः वांछनीय जॉइन वाले कॉलम भी होते हैं जिन्हें NULL होने की अनुमति होती है। कई रिपोर्टिंग रिलेशनल डेटाबेस और डेटा वेयरहाउस हाई वॉल्यूम ्सट्रैक्ट, ट्रांसफॉर्म, लोड (ईटीएल) बैच अपडेट का उपयोग करते हैं जो संदर्भात्मक अखंडता को लागू करना मुश्किल या असंभव बनाते हैं, जिसके परिणामस्वरूप संभावित रूप से NULL जॉइन कॉलम होते हैं जिन्हें एसक्यूएल क्वेरी लेखक संशोधित नहीं कर सकता है और जो किसी त्रुटि के संकेत के बिना डेटा को छोड़ने के लिए इनर जॉइन का कारण बनता है। इनर जॉइन का उपयोग करने का विकल्प डेटाबेस डिज़ाइन और डेटा विशेषताओं पर निर्भर करता है। जब तालिका में सम्मिलित कॉलम में NULL मान हो सकते हैं, तो बाएं बाहरी जॉइन को सामान्यतः इनर जॉइन के लिए प्रतिस्थापित किया जा सकता है।
कोई भी डेटा कॉलम जो NULL (खाली) हो सकता है, उसे कभी भी इनर जॉइन में लिंक के रूप में उपयोग नहीं किया जाना चाहिए, जब तक कि इच्छित परिणाम NULL मान वाली पंक्तियों को खत्म करना न हो। यदि परिणाम सेट से NULL जॉइन कॉलम को जानबूझकर हटाया जाना है, तो इनर जॉइन बाहरी जॉइन से तेज़ हो सकता है क्योंकि टेबल जॉइन और फ़िल्टरिंग ही चरण में की जाती है। इसके विपरीत, एसक्यूएल व्हेयर क्लॉज में डेटाबेस फ़ंक्शंस के साथ संयोजन में बड़ी मात्रा में क्वेरी में उपयोग किए जाने पर इनर जॉइन के परिणामस्वरूप विनाशकारी रूप से धीमा प्रदर्शन या सर्वर क्रैश भी हो सकता है।[2][3][4] एसक्यूएल व्हेयर क्लॉज़ में फ़ंक्शन के परिणामस्वरूप डेटाबेस अपेक्षाकृत कॉम्पैक्ट टेबल इंडेक्स को अनदेखा कर सकता है। गणना किए गए मान पर निर्भर फ़िल्टर का उपयोग करके पंक्तियों की संख्या को कम करने से पहले डेटाबेस दोनों तालिकाओं से चयनित कॉलम को पढ़ और इनर रूप से जोड़ सकता है, जिसके परिणामस्वरूप अपेक्षाकृत भारी मात्रा में अकुशल प्रसंस्करण होता है।
जब परिणाम सेट कई तालिकाओं को जोड़कर तैयार किया जाता है, जिसमें संख्यात्मक पहचानकर्ता कोड ( लुकअप तालिका) के पूर्ण-पाठ विवरण देखने के लिए उपयोग की जाने वाली मास्टर तालिकाएं भी सम्मिलित होती हैं, तो विदेशी कुंजी में से किसी में शून्य मान के परिणामस्वरूप परिणाम सेट से पूरी पंक्ति को हटाया जा सकता है, त्रुटि का कोई संकेत नहीं। जटिल एसक्यूएल क्वेरी जिसमें या अधिक इनर जोड़ और कई बाहरी जोड़ सम्मिलित होते हैं, इनर जॉइन लिंक कॉलम में NULL मानों के लिए समान जोखिम होता है।
इनर जॉइन वाले एसक्यूएल कोड के प्रति प्रतिबद्धता यह मानती है कि NULL जॉइन कॉलम को भविष्य में होने वाले बदलावों द्वारा पेश नहीं किया जाएगा, जिसमें विक्रेता अपडेट, डिज़ाइन परिवर्तन और एप्लिकेशन के डेटा सत्यापन नियमों के बाहर बल्क प्रोसेसिंग जैसे डेटा रूपांतरण, माइग्रेशन, बल्क आयात और मर्ज सम्मिलित हैं।
इनर जोड़ को आगे चलकर समान जोड़, प्राकृतिक जोड़ या क्रॉस-जोड़ के रूप में वर्गीकृत किया जा सकता है।
इक्वि-जॉइन
इक्वि-जॉइन विशिष्ट प्रकार का तुलनित्र-आधारित जॉइन है, जो जॉइन-प्रेडिकेट में केवल समानता (गणित) तुलना का उपयोग करता है। अन्य तुलना ऑपरेटरों का उपयोग करना (जैसे <
) जॉइन को इक्वि-जॉइन के रूप में अयोग्य घोषित करता है। ऊपर दिखाई गई क्वेरी पहले ही समान-जॉइन का उदाहरण प्रदान कर चुकी है:
SELECT *
FROM employee JOIN department
ON employee.DepartmentID = department.DepartmentID;
हम इक्वी-जॉइन को नीचे इस प्रकार लिख सकते हैं,
SELECT *
FROM employee, department
WHERE employee.DepartmentID = department.DepartmentID;
यदि इक्वि-जॉइन में कॉलमों का नाम समान है, तो SQL-92 इक्वि-जॉइन को व्यक्त करने के लिए वैकल्पिक शॉर्टहैंड नोटेशन प्रदान करता है। USING
निर्माण:[5]
SELECT *
FROM employee INNER JOIN department USING (DepartmentID);
USING
ई> निर्माण केवल वाक्यात्मक चीनी से अधिक है, हालांकि, परिणाम सेट स्पष्ट प्रेडिकेट के साथ संस्करण के परिणाम सेट से भिन्न होता है। विशेष रूप से, में उल्लिखित कोई भी कॉलमUSING
सूची सम्मिलित होने वाली प्रत्येक तालिका के लिए बार के बजाय केवल बार अयोग्य नाम के साथ दिखाई देगी। उपरोक्त मामले में, ल होगाDepartmentID
कॉलम और नंemployee.DepartmentID
याdepartment.DepartmentID
.USING
e> क्लॉज MS एसक्यूएल सर्वर और Sybase द्वारा समर्थित नहीं है।
प्राकृतिक जॉइन
प्राकृतिक जॉइन सम-जुड़ का विशेष मामला है। प्राकृतिक जॉइन (⋈) द्विआधारी संबंध है जिसे (आर ⋈ एस) के रूप में लिखा जाता है जहां आर और एस संबंध (डेटाबेस) हैं।[6] प्राकृतिक जॉइन का परिणाम आर और एस में टुपल्स के सभी संयोजनों का सेट है जो उनके सामान्य विशेषता नामों पर समान हैं। उदाहरण के लिए कर्मचारी और विभाग और उनके स्वाभाविक जॉइन तालिकाओं पर विचार करें:
|
|
|
इसका उपयोग संबंधों की संरचना को परिभाषित करने के लिए भी किया जा सकता है। उदाहरण के लिए, कर्मचारी और विभाग की संरचना उनका जॉइन है जैसा कि ऊपर दिखाया गया है, सामान्य विशेषता विभागनाम को छोड़कर सभी पर प्रक्षेपित किया गया है। श्रेणी सिद्धांत में, जॉइन बिल्कुल फाइबर उत्पाद है।
प्राकृतिक जॉइन यकीनन सबसे महत्वपूर्ण ऑपरेटरों में से है क्योंकि यह तार्किक AND का संबंधपरक समकक्ष है। ध्यान दें कि यदि AND से जुड़े दो विधेयों में से प्रत्येक में ही चर दिखाई देता है, तो वह चर ही चीज़ के लिए खड़ा होता है और दोनों दिखावे को हमेशा ही मान से प्रतिस्थापित किया जाना चाहिए। विशेष रूप से, प्राकृतिक जॉइन उन संबंधों के संयोजन की अनुमति देता है जो किसी विदेशी कुंजी से जुड़े होते हैं। उदाहरण के लिए, उपरोक्त उदाहरण में विदेशी कुंजी संभवतः Employee.DeptName से Dept.DeptName तक होती है और फिर कर्मचारी और विभाग का प्राकृतिक जॉइन सभी कर्मचारियों को उनके विभागों के साथ जोड़ता है। यह काम करता है क्योंकि विदेशी कुंजी समान नाम वाली विशेषताओं के बीच रहती है। यदि ऐसा मामला नहीं है जैसे विभाग प्रबंधक से कर्मचारी नाम तक की विदेशी कुंजी में तो प्राकृतिक जॉइन लेने से पहले इन कॉलमों का नाम बदलना होगा। इस तरह के जॉइन को कभी-कभी 'इक्वी-जॉइन' भी कहा जाता है।
अधिक औपचारिक रूप से प्राकृतिक जॉइन के शब्दार्थ को इस प्रकार परिभाषित किया गया है:
- ,
जहां फन प्रेडिकेट (गणित) है जो संबंध (गणित) आर के लिए सत्य है यदि और केवल यदि आर फ़ंक्शन है। सामान्यतः यह आवश्यक है कि आर और एस में कम से कम सामान्य विशेषता होनी चाहिए, किन्तु यदि इस बाधा को छोड़ दिया जाता है, और आर और एस में कोई सामान्य विशेषता नहीं है, तो प्राकृतिक जॉइन बिल्कुल कार्टेशियन उत्पाद बन जाता है।
प्राकृतिक जॉइन को कोडड के आदिमों के साथ निम्नानुसार अनुकरण किया जा सकता है। चलो सी1, ..., सीm आर और एस, आर के लिए सामान्य विशेषता नाम बनें1, ..., आरn आर और लेट एस के लिए अद्वितीय विशेषता नाम बनें1, ..., एसk एस के लिए अद्वितीय विशेषताएँ बनें। इसके अलावा, मान लें कि विशेषता नाम x है1, ..., ्सm न तो आर में हैं और न ही एस में। पहले चरण में अब एस में सामान्य विशेषता नामों का नाम बदला जा सकता है:
फिर हम कार्टेशियन उत्पाद लेते हैं और उन टुपल्स का चयन करते हैं जिन्हें जोड़ा जाना है:
प्राकृतिक जॉइन प्रकार का इक्वि-जॉइन है जहां जॉइन प्रेडिकेट दोनों तालिकाओं में सभी कॉलमों की तुलना करके अंतर्निहित रूप से उत्पन्न होता है, जिसमें सम्मिलित तालिकाओं में समान कॉलम-नाम होते हैं। परिणामी सम्मिलित तालिका में समान रूप से नामित स्तंभों की प्रत्येक जोड़ी के लिए केवल स्तंभ होता है। ऐसी स्थिति में जब समान नाम वाला कोई कॉलम नहीं मिलता है, तो परिणाम क्रॉस जॉइन होता है।
अधिकांश विशेषज्ञ इस बात से सहमत हैं कि प्राकृतिक जोड़ खतरनाक हैं और इसलिए उनके उपयोग को दृढ़ता से हतोत्साहित करते हैं।[7] खतरा अनजाने में नया कॉलम जोड़ने से आता है, जिसका नाम दूसरी तालिका के दूसरे कॉलम के समान है। मौजूदा प्राकृतिक जोड़ स्वाभाविक रूप से तुलना के लिए नए कॉलम का उपयोग कर सकता है, पहले की तुलना में विभिन्न मानदंडों (विभिन्न कॉलमों से) का उपयोग करके तुलना/मिलान कर सकता है। इस प्रकार मौजूदा क्वेरी अलग-अलग परिणाम दे सकती है, भले ही तालिकाओं में डेटा बदला नहीं गया है, बल्कि केवल संवर्धित किया गया है। तालिका लिंक को स्वचालित रूप से निर्धारित करने के लिए कॉलम नामों का उपयोग सैकड़ों या हजारों तालिकाओं वाले बड़े डेटाबेस में विकल्प नहीं है, जहां यह नामकरण परंपराओं पर अवास्तविक बाधा डालेगा। वास्तविक दुनिया के डेटाबेस सामान्यतः विदेशी कुंजी डेटा के साथ डिज़ाइन किए जाते हैं जो व्यावसायिक नियमों और संदर्भ के कारण लगातार पॉप्युलेट नहीं होते हैं (शून्य मानों की अनुमति है)। विभिन्न तालिकाओं में समान डेटा के कॉलम नामों को संशोधित करना आम बात है और कठोर स्थिरता की यह कमी प्राकृतिक जॉइन को चर्चा के लिए सैद्धांतिक अवधारणा में बदल देती है।
इनर जॉइन के लिए उपरोक्त नमूना क्वेरी को प्राकृतिक जॉइन के रूप में निम्नलिखित तरीके से व्यक्त किया जा सकता है:
SELECT *
FROM employee NATURAL JOIN department;
स्पष्ट के साथ के रूप में USING
खंड, सम्मिलित तालिका में केवल डिपार्टमेंटआईडी कॉलम होता है, जिसमें कोई क्वालीफायर नहीं होता है:
DepartmentID | Employee.LastName | Department.DepartmentName |
---|---|---|
34 | स्मिथ | क्लेरिकल |
33 | जोन्स | इंजीनियरिंग |
34 | रॉबिंसन | क्लेरिकल |
33 | हाइजेनबर्ग | इंजीनियरिंग |
31 | रैफर्टी | सेल्स |
PostgreSQL, Myएसक्यूएल और Oracle प्राकृतिक जॉइन का समर्थन करते हैं; Microsoft T-एसक्यूएल और IBM DB2 नहीं करते हैं। जॉइन में उपयोग किए गए कॉलम अंतर्निहित हैं, इसलिए जॉइन कोड यह नहीं दिखाता है कि कौन से कॉलम अपेक्षित हैं, और कॉलम नामों में बदलाव से परिणाम बदल सकते हैं। SQL:2011 मानक में, प्राकृतिक जोड़ वैकल्पिक F401, विस्तारित सम्मिलित तालिका, पैकेज का हिस्सा हैं।
कई डेटाबेस परिवेशों में कॉलम नाम किसी बाहरी विक्रेता द्वारा नियंत्रित होते हैं, क्वेरी डेवलपर द्वारा नहीं। प्राकृतिक जॉइन कॉलम नामों में स्थिरता और स्थिरता मानता है जो विक्रेता द्वारा अनिवार्य संस्करण अपग्रेड के दौरान बदल सकता है।
बाहरी जॉइन
सम्मिलित तालिका प्रत्येक पंक्ति को बरकरार रखती है - भले ही कोई अन्य मिलान पंक्ति मौजूद न हो। बाहरी जोड़ को बाएँ बाहरी जोड़, दाएँ बाहरी जोड़ और पूर्ण बाहरी जोड़ में उप-विभाजित किया जाता है, यह इस पर निर्भर करता है कि किस तालिका की पंक्तियाँ बरकरार रखी गई हैं: बाएँ, दाएँ, या दोनों (इस मामले में बाएँ और दाएँ तालिका के दो पक्षों को संदर्भित करते हैं) JOIN
कीवर्ड)। #इनर जॉइन की तरह, कोई भी सभी प्रकार के बाहरी जॉइन को #इक्वि-जॉइन|इक्वि-जॉइन, #नेचुरल जॉइन, के रूप में उप-वर्गीकृत कर सकता है। ON <predicate>
(रिलेशनल अलजेब्रा#θ-जॉइन और इक्विजॉइन|θ-जॉइन), आदि।[8]
मानक एसक्यूएल में बाहरी जॉइनों के लिए कोई अंतर्निहित जॉइन-नोटेशन मौजूद नहीं है।
बायां बाहरी जॉइन
तालिका ए और बी के लिए बाएं बाहरी जोड़ (या बस बाएं जोड़) के परिणाम में हमेशा बाईं तालिका (ए) की सभी पंक्तियां सम्मिलित होती हैं, भले ही सम्मिलित होने की स्थिति को सही तालिका (बी) में कोई मिलान पंक्ति नहीं मिलती है। इसका मतलब यह है कि यदि ON
क्लॉज़ बी में 0 (शून्य) पंक्तियों से मेल खाता है (ए में दी गई पंक्ति के लिए), जॉइन अभी भी परिणाम में पंक्ति लौटाएगा (उस पंक्ति के लिए) - किन्तु बी से प्रत्येक कॉलम में शून्य के साथ। बायां बाहरी जॉइन सभी को लौटाता है इनर जॉइन के मान और बाईं तालिका के सभी मान जो दाहिनी तालिका से मेल नहीं खाते हैं, जिसमें लिंक कॉलम में NULL (खाली) मान वाली पंक्तियाँ भी सम्मिलित हैं।
उदाहरण के लिए, यह हमें किसी कर्मचारी का विभाग ढूंढने की अनुमति देता है, किन्तु फिर भी उन कर्मचारियों को दिखाता है जिन्हें किसी विभाग को नहीं सौंपा गया है (ऊपर दिए गए इनर-जॉइन उदाहरण के विपरीत, जहां बिना असाइन किए गए कर्मचारियों को परिणाम से बाहर रखा गया था)।
बाएँ बाहरी जॉइन का उदाहरण (दOUTER
कीवर्ड वैकल्पिक है), अतिरिक्त परिणाम पंक्ति (इनर जॉइन की तुलना में) इटैलिकाइज़्ड के साथ:
SELECT *
FROM employee
LEFT OUTER JOIN department ON employee.DepartmentID = department.DepartmentID;
Employee.LastName | Employee.DepartmentID | Department.DepartmentName | Department.DepartmentID |
---|---|---|---|
जोन्स | 33 | इंजीनियरिंग | 33 |
रैफर्टी | 31 | सेल्स | 31 |
रॉबिंसन | 34 | क्लेरिकल | 34 |
स्मिथ | 34 | क्लेरिकल | 34 |
विलियम्स | NULL |
NULL |
NULL
|
हाइजेनबर्ग | 33 | इंजीनियरिंग | 33 |
वैकल्पिक वाक्यविन्यास
ओरेकल बहिष्कृत का समर्थन करता है[9] सिंटैक्स:
SELECT *
FROM employee, department
WHERE employee.DepartmentID = department.DepartmentID(+)
Sybase सिंटैक्स का समर्थन करता है (Microsoft एसक्यूएल सर्वर ने संस्करण 2000 से इस सिंटैक्स को हटा दिया है):
SELECT *
FROM employee, department
WHERE employee.DepartmentID *= department.DepartmentID
IBM Informix सिंटैक्स का समर्थन करता है:
SELECT *
FROM employee, OUTER department
WHERE employee.DepartmentID = department.DepartmentID
दायां बाहरी जॉइन
दायां बाहरी जोड़ (या दायां जोड़) बाएं बाहरी जोड़ से काफी मिलता-जुलता है, सिवाय तालिकाओं के उलटे व्यवहार के। दाहिनी तालिका (बी) से प्रत्येक पंक्ति कम से कम बार सम्मिलित तालिका में दिखाई देगी। यदि बाईं तालिका (ए) से कोई मिलान पंक्ति मौजूद नहीं है, तो NULL उन पंक्तियों के लिए ए से कॉलम में दिखाई देगा जिनका बी में कोई मिलान नहीं है।
दायां बाहरी जोड़ दाहिनी तालिका से सभी मान लौटाता है और बाईं तालिका से मिलान किए गए मान लौटाता है (कोई मिलान न होने की स्थिति में NULL)। उदाहरण के लिए, यह हमें प्रत्येक कर्मचारी और उसके विभाग को ढूंढने की अनुमति देता है, किन्तु फिर भी ऐसे विभाग दिखाता है जिनमें कोई कर्मचारी नहीं है।
नीचे दाएं बाहरी जॉइन का उदाहरण दिया गया है (दOUTER
कीवर्ड वैकल्पिक है), अतिरिक्त परिणाम पंक्ति इटैलिकाइज़्ड के साथ:
SELECT *
FROM employee RIGHT OUTER JOIN department
ON employee.DepartmentID = department.DepartmentID;
Employee.LastName | Employee.DepartmentID | Department.DepartmentName | Department.DepartmentID |
---|---|---|---|
स्मिथ | 34 | क्लेरिकल | 34 |
जोन्स | 33 | इंजीनियरिंग | 33 |
रॉबिंसन | 34 | क्लेरिकल | 34 |
हाइजेनबर्ग | 33 | इंजीनियरिंग | 33 |
रैफर्टी | 31 | सेल्स | 31 |
NULL |
NULL |
मार्केटिंग | 35 |
दाएं और बाएं बाहरी जोड़ कार्यात्मक रूप से समतुल्य हैं। इनमें से कोई भी ऐसी कोई कार्यक्षमता प्रदान नहीं करता है जो दूसरा नहीं करता है, इसलिए जब तक तालिका क्रम स्विच किया जाता है तब तक दाएं और बाएं बाहरी जोड़ -दूसरे को प्रतिस्थापित कर सकते हैं।
पूर्ण बाहरी जॉइन
वैचारिक रूप से, पूर्ण बाहरी जॉइन बाएँ और दाएँ दोनों बाहरी जॉइनों को लागू करने के प्रभाव को जोड़ता है। जहां पूर्ण बाहरी सम्मिलित तालिकाओं में पंक्तियाँ मेल नहीं खातीं, परिणाम सेट में तालिका के प्रत्येक कॉलम के लिए NULL मान होंगे जिनमें मिलान पंक्ति का अभाव है। उन पंक्तियों के लिए जो मेल खाती हैं, परिणाम सेट में ल पंक्ति तैयार की जाएगी (जिसमें दोनों तालिकाओं से भरे गए कॉलम होंगे)।
उदाहरण के लिए, यह हमें प्रत्येक कर्मचारी को देखने की अनुमति देता है जो विभाग में है और प्रत्येक विभाग जिसमें कर्मचारी है, किन्तु प्रत्येक कर्मचारी को भी देख सकता है जो विभाग का हिस्सा नहीं है और प्रत्येक विभाग जिसमें कर्मचारी नहीं है।
पूर्ण बाहरी जोड़ का उदाहरण (OUTER
कीवर्ड वैकल्पिक है):
SELECT *
FROM employee FULL OUTER JOIN department
ON employee.DepartmentID = department.DepartmentID;
Employee.LastName | Employee.DepartmentID | Department.DepartmentName | Department.DepartmentID |
---|---|---|---|
स्मिथ | 34 | क्लेरिकल | 34 |
जोन्स | 33 | इंजीनियरिंग | 33 |
रॉबिंसन | 34 | क्लेरिकल | 34 |
विलियम्स | NULL |
NULL |
NULL
|
हाइजेनबर्ग | 33 | इंजीनियरिंग | 33 |
रैफर्टी | 31 | सेल्स | 31 |
NULL |
NULL |
मार्केटिंग | 35 |
कुछ डेटाबेस प्रणालियाँ सीधे पूर्ण बाहरी जॉइन कार्यक्षमता का समर्थन नहीं करती हैं, किन्तु वे क्रमशः बाएँ और दाएँ तालिकाओं से ल तालिका पंक्तियों के सभी चयनों और इनर जॉइन के उपयोग के माध्यम से इसका अनुकरण कर सकते हैं। वही उदाहरण इस प्रकार दिखाई दे सकता है:
SELECT employee.LastName, employee.DepartmentID,
department.DepartmentName, department.DepartmentID
FROM employee
INNER JOIN department ON employee.DepartmentID = department.DepartmentID
UNION ALL
SELECT employee.LastName, employee.DepartmentID,
cast(NULL as varchar(20)), cast(NULL as integer)
FROM employee
WHERE NOT EXISTS (
SELECT * FROM department
WHERE employee.DepartmentID = department.DepartmentID)
UNION ALL
SELECT cast(NULL as varchar(20)), cast(NULL as integer),
department.DepartmentName, department.DepartmentID
FROM department
WHERE NOT EXISTS (
SELECT * FROM employee
WHERE employee.DepartmentID = department.DepartmentID)
अन्य दृष्टिकोण यूनियन हो सकता है, सभी बाएँ बाहरी जोड़ और दाएँ बाहरी जोड़ माइनस इनर जॉइन।
स्वयं-जुड़ना
सेल्फ-जॉइन टेबल को खुद से जोड़ना है।[10]
उदाहरण
यदि कर्मचारियों के लिए दो अलग-अलग तालिकाएँ थीं और क्वेरी जिसमें पहली तालिका में कर्मचारियों से दूसरी तालिका में कर्मचारियों के समान देश का अनुरोध किया गया था, तो उत्तर तालिका खोजने के लिए सामान्य जॉइन ऑपरेशन का उपयोग किया जा सकता था। हालाँकि, सभी कर्मचारी जानकारी ही बड़ी तालिका में समाहित है।[11]
संशोधित पर विचार करें Employee
तालिका जैसे कि निम्नलिखित:
EmployeeID | LastName | Country | DepartmentID |
---|---|---|---|
123 | रैफर्टी | ऑस्ट्रेलिया | 31 |
124 | जोन्स | ऑस्ट्रेलिया | 33 |
145 | हाइजेनबर्ग | ऑस्ट्रेलिया | 33 |
201 | रॉबिंसन | यूनाइटेड स्टेट्स | 34 |
305 | स्मिथ | जर्मनी | 34 |
306 | विलियम्स | जर्मनी | NULL
|
उदाहरण समाधान क्वेरी इस प्रकार हो सकती है:
SELECT F.EmployeeID, F.LastName, S.EmployeeID, S.LastName, F.Country
FROM Employee F INNER JOIN Employee S ON F.Country = S.Country
WHERE F.EmployeeID < S.EmployeeID
ORDER BY F.EmployeeID, S.EmployeeID;
जिसके परिणामस्वरूप निम्न तालिका उत्पन्न होती है।
EmployeeID | LastName | EmployeeID | LastName | Country |
---|---|---|---|---|
123 | रैफर्टी | 124 | जोन्स | ऑस्ट्रेलिया |
123 | रैफर्टी | 145 | हाइजेनबर्ग | ऑस्ट्रेलिया |
124 | जोन्स | 145 | हाइजेनबर्ग | ऑस्ट्रेलिया |
305 | स्मिथ | 306 | विलियम्स | जर्मनी |
इस उदाहरण के लिए:
F
औरS
कर्मचारी तालिका की पहली और दूसरी प्रतियों के लिए उपनाम (एसक्यूएल) हैं।- स्थिति
F.Country = S.Country
विभिन्न देशों में कर्मचारियों के बीच युग्मों को सम्मिलित नहीं किया गया है। उदाहरण प्रश्न केवल ही देश में कर्मचारियों के जोड़े चाहता था। - स्थिति
F.EmployeeID < S.EmployeeID
जहां जोड़ों को सम्मिलित नहीं किया गया हैEmployeeID
पहले कर्मचारी से अधिक या उसके बराबर हैEmployeeID
दूसरे कर्मचारी का. दूसरे शब्दों में, इस शर्त का प्रभाव डुप्लिकेट जोड़ियों और स्वयं-जोड़ियों को बाहर करना है। इसके बिना, निम्नलिखित कम उपयोगी तालिका तैयार की जाएगी (नीचे दी गई तालिका परिणाम का केवल जर्मनी भाग प्रदर्शित करती है):
EmployeeID | LastName | EmployeeID | LastName | Country |
---|---|---|---|---|
305 | स्मिथ | 305 | स्मिथ | जर्मनी |
305 | स्मिथ | 306 | विलियम्स | जर्मनी |
306 | विलियम्स | 305 | स्मिथ | जर्मनी |
306 | विलियम्स | 306 | विलियम्स | जर्मनी |
मूल प्रश्न को संतुष्ट करने के लिए दो मध्य युग्मों में से केवल की आवश्यकता है, और सबसे ऊपर और सबसे नीचे वाले को इस उदाहरण में कोई दिलचस्पी नहीं है।
विकल्प
बाहरी जॉइन का प्रभाव इनर जॉइन और मुख्य तालिका में उन पंक्तियों के चयन के बीच यूनियन ऑल का उपयोग करके भी प्राप्त किया जा सकता है जो जुड़ने की शर्त को पूरा नहीं करते हैं। उदाहरण के लिए,
SELECT employee.LastName, employee.DepartmentID, department.DepartmentName
FROM employee
LEFT OUTER JOIN department ON employee.DepartmentID = department.DepartmentID;
के रूप में भी लिखा जा सकता है
SELECT employee.LastName, employee.DepartmentID, department.DepartmentName
FROM employee
INNER JOIN department ON employee.DepartmentID = department.DepartmentID
UNION ALL
SELECT employee.LastName, employee.DepartmentID, cast(NULL as varchar(20))
FROM employee
WHERE NOT EXISTS (
SELECT * FROM department
WHERE employee.DepartmentID = department.DepartmentID)
कार्यान्वयन
डेटाबेस-सिस्टम में बहुत से काम का उद्देश्य जॉइन के कुशल कार्यान्वयन पर है, क्योंकि रिलेशनल सिस्टम सामान्यतः जॉइन की मांग करते हैं, फिर भी उनके कुशल निष्पादन को अनुकूलित करने में कठिनाइयों का सामना करना पड़ता है। समस्या इसलिए उत्पन्न होती है क्योंकि इनर जोड़ क्रमविनिमेय और साहचर्य दोनों तरह से काम करते हैं। व्यवहार में, इसका मतलब यह है कि उपयोगकर्ता केवल जुड़ने के लिए तालिकाओं की सूची और उपयोग करने के लिए जुड़ने की शर्तों की आपूर्ति करता है, और डेटाबेस सिस्टम के पास ऑपरेशन करने का सबसे कुशल तरीका निर्धारित करने का कार्य होता है। क्वेरी अनुकूलक यह निर्धारित करता है कि जॉइन वाली क्वेरी को कैसे निष्पादित किया जाए। क्वेरी ऑप्टिमाइज़र में दो बुनियादी स्वतंत्रताएँ होती हैं:
- जुड़ने का क्रम: क्योंकि यह कार्यों को क्रमविनिमेय और साहचर्य रूप से जोड़ता है, जिस क्रम में सिस्टम तालिकाओं से जुड़ता है वह क्वेरी के अंतिम परिणाम सेट को नहीं बदलता है। हालाँकि, जॉइन-ऑर्डर का जॉइन ऑपरेशन की लागत पर भारी प्रभाव पड़ सकता है, इसलिए सबसे अच्छा जॉइन ऑर्डर चुनना बहुत महत्वपूर्ण हो जाता है।
- सम्मिलित होने की विधि: दो तालिकाओं और जुड़ने की स्थिति को देखते हुए, कई कलन विधि सम्मिलित होने के परिणाम सेट का उत्पादन कर सकते हैं। कौन सा एल्गोरिदम सबसे अधिक कुशलता से चलता है यह इनपुट तालिकाओं के आकार, प्रत्येक तालिका से जुड़ने की स्थिति से मेल खाने वाली पंक्तियों की संख्या और बाकी क्वेरी के लिए आवश्यक संचालन पर निर्भर करता है।
कई जॉइन-एल्गोरिदम अपने इनपुट को अलग तरह से व्यवहार करते हैं। किसी जॉइन के इनपुट को क्रमशः बाहरी और इनर जॉइन ऑपरेंड, या बाएँ और दाएँ के रूप में संदर्भित किया जा सकता है। उदाहरण के लिए, नेस्टेड लूप के मामले में, डेटाबेस सिस्टम बाहरी संबंध की प्रत्येक पंक्ति के लिए संपूर्ण इनर संबंध को स्कैन करेगा।
कोई भी सम्मिलित होने वाली क्वेरी-योजनाओं को निम्नानुसार वर्गीकृत कर सकता है:[12]
- लेफ्ट-डीप
- योजना में प्रत्येक जॉइन के इनर ऑपरेंड के रूप में बेस टेबल (किसी अन्य जॉइन के बजाय) का उपयोग करना
- राइट-डीप
- योजना में प्रत्येक जॉइन के बाहरी ऑपरेंड के रूप में बेस टेबल का उपयोग करना
- झाड़ीदार
- न बाएँ-गहरा, न दाएँ-गहरा; किसी जॉइन के दोनों इनपुट स्वयं जॉइन के परिणामस्वरूप हो सकते हैं
यदि ट्री डेटा संरचना के रूप में तैयार किया जाता है, तो ये नाम क्वेरी योजना की उपस्थिति से प्राप्त होते हैं, जिसमें बाईं ओर बाहरी जॉइन संबंध और दाईं ओर इनर संबंध होता है (जैसा कि सम्मेलन तय करता है)।
एल्गोरिदम से जुड़ें
![](https://upload.wikimedia.org/wikipedia/commons/thumb/d/d8/Comparison_of_join_algorithms.png/300px-Comparison_of_join_algorithms.png)
बाइनरी जॉइन ऑपरेशन करने के लिए तीन मौलिक एल्गोरिदम मौजूद हैं: नेस्टेड लूप जॉइन, सॉर्ट-मर्ज जॉइन और हैश जॉइन। सबसे खराब स्थिति में इष्टतम जॉइन एल्गोरिदम, सबसे खराब स्थिति में दो से अधिक संबंधों के बीच जुड़ने के लिए बाइनरी जॉइन एल्गोरिदम की तुलना में एसिम्प्टोटिक रूप से तेज़ हैं।
जॉइन इन्डेक्सेस
जॉइन इंडेक्स डेटाबेस सूचकांक हैं जो डेटा वेयरहाउस में जॉइन क्वेरी के प्रसंस्करण की सुविधा प्रदान करते हैं: वे वर्तमान में (2012) ओरेकल डेटाबेस द्वारा कार्यान्वयन में उपलब्ध हैं[14] और टेराडाटा.[15] टेराडाटा कार्यान्वयन में, निर्दिष्ट कॉलम, कॉलम पर समग्र कार्य, या या अधिक तालिकाओं से दिनांक कॉलम के घटकों को डेटाबेस दृश्य की परिभाषा के समान सिंटैक्स का उपयोग करके निर्दिष्ट किया जाता है: 64 कॉलम/कॉलम अभिव्यक्तियों को ल में निर्दिष्ट किया जा सकता है सूचकांक में सम्मिलित हों. वैकल्पिक रूप से, कॉलम जो समग्र डेटा की प्राथमिक कुंजी को परिभाषित करता है, उसे भी निर्दिष्ट किया जा सकता है: समानांतर हार्डवेयर पर, कॉलम मानों का उपयोग सूचकांक की सामग्री को कई डिस्क में विभाजित करने के लिए किया जाता है। जब स्रोत तालिकाओं को उपयोगकर्ताओं द्वारा इंटरैक्टिव रूप से अपडेट किया जाता है, तो जॉइन इंडेक्स की सामग्री स्वचालित रूप से अपडेट हो जाती है। कोई भी क्वेरी जिसका कहां (एसक्यूएल) कॉलम या कॉलम ्सप्रेशन के किसी भी संयोजन को निर्दिष्ट करता है जो कि जॉइन इंडेक्स (तथाकथित कवरिंग क्वेरी) में परिभाषित लोगों का सटीक सबसेट है, मूल तालिकाओं और उनके इंडेक्स के बजाय जॉइन इंडेक्स का कारण बनेगा, क्वेरी निष्पादन के दौरान परामर्श लिया जाना।
Oracle कार्यान्वयन स्वयं को बिटमैप सूचकांक का उपयोग करने तक सीमित रखता है। बिटमैप जॉइन इंडेक्स का उपयोग कम-कार्डिनैलिटी कॉलम के लिए किया जाता है (यानी, ओरेकल दस्तावेज़ के अनुसार 300 से कम विशिष्ट मान वाले कॉलम): यह कई संबंधित तालिकाओं से कम-कार्डिनैलिटी कॉलम को जोड़ता है। Oracle जिस उदाहरण का उपयोग करता है वह इन्वेंट्री सिस्टम का है, जहां विभिन्न आपूर्तिकर्ता अलग-अलग हिस्से प्रदान करते हैं। डेटाबेस स्कीमा में तीन लिंक्ड टेबल हैं: दो मास्टर टेबल, पार्ट और सप्लायर, और डिटेल टेबल, इन्वेंटरी। अंतिम अनेक-से-अनेक तालिका है जो आपूर्तिकर्ता को भाग से जोड़ती है, और इसमें सबसे अधिक पंक्तियाँ होती हैं। प्रत्येक भाग का भाग प्रकार होता है, और प्रत्येक आपूर्तिकर्ता अमेरिका में स्थित होता है, और उसके पास राज्य कॉलम होता है। अमेरिका में 60 से अधिक राज्य+क्षेत्र नहीं हैं, और 300 से अधिक भाग प्रकार नहीं हैं। बिटमैप जॉइन इंडेक्स को उपरोक्त तीन तालिकाओं पर मानक तीन-टेबल जॉइन का उपयोग करके परिभाषित किया गया है, और इंडेक्स के लिए पार्ट_टाइप और सप्लायर_स्टेट कॉलम निर्दिष्ट किया गया है। हालाँकि, इसे इन्वेंटरी टेबल पर परिभाषित किया गया है, भले ही कॉलम पार्ट_टाइप और सप्लायर_स्टेट क्रमशः सप्लायर और पार्ट से उधार लिए गए हों।
टेराडेटा के लिए, ओरेकल बिटमैप जॉइन इंडेक्स का उपयोग केवल प्रश्न का उत्तर देने के लिए किया जाता है जब क्वेरी का व्हेयर (एसक्यूएल) उन कॉलमों तक सीमित होता है जो जॉइन इंडेक्स में सम्मिलित होते हैं।
स्ट्रैट जॉइन
कुछ डेटाबेस सिस्टम उपयोगकर्ता को सिस्टम को विशेष क्रम में तालिकाओं को पढ़ने के लिए बाध्य करने की अनुमति देते हैं। इसका उपयोग तब किया जाता है जब जॉइन ऑप्टिमाइज़र तालिकाओं को अकुशल क्रम में पढ़ने का विकल्प चयन किया जाता है। उदाहरण के लिए, Myएसक्यूएल में कमांड STRAIGHT_JOIN
तालिकाओं को क्वेरी में सूचीबद्ध क्रम में ही पढ़ता है।[16]
यह भी देखें
- जुड़ें (संबंधपरक बीजगणित)
- एंटीजॉइन
- सेट ऑपरेशन (एसक्यूएल)
संदर्भ
उद्धरण
- ↑ SQL CROSS JOIN
- ↑ Greg Robidoux, "Avoid SQL Server functions in the WHERE clause for Performance", MSSQL Tips, 3 May 2007
- ↑ Patrick Wolf, "Inside Oracle APEX "Caution when using PL/SQL functions in a SQL statement", 30 November 2006
- ↑ Gregory A. Larsen, "T-SQL Best Practices - Don't Use Scalar Value Functions in Column List or WHERE Clauses", 29 October 2009,
- ↑ Simplifying Joins with the USING Keyword
- ↑ In Unicode, the bowtie symbol is ⋈ (U+22C8).
- ↑ Ask Tom "Oracle support of ANSI joins." Back to basics: inner joins » Eddie Awad's Blog Archived 2010-11-19 at the Wayback Machine
- ↑ Silberschatz, Abraham; Korth, Hank; Sudarshan, S. (2002). "Section 4.10.2: Join Types and Conditions". डेटाबेस सिस्टम अवधारणाएँ (4th ed.). p. 166. ISBN 0072283637.
- ↑ Oracle लेफ्ट आउटर जॉइन
- ↑ Shah 2005, p. 165
- ↑ Adapted from Pratt 2005, pp. 115–6
- ↑ Yu & Meng 1998, p. 213
- ↑ Wang, Yisu Remy; Willsey, Max; Suciu, Dan (2023-01-27). "Free Join: Unifying Worst-Case Optimal and Traditional Joins". arXiv:2301.10841 [cs.DB].
- ↑ Oracle Bitmap Join Index. URL: http://www.dba-oracle.com/art_builder_bitmap_join_idx.htm
- ↑ Teradata Join Indexes. "Join Index". Archived from the original on 2012-12-16. Retrieved 2012-06-14.
- ↑ "13.2.9.2 JOIN Syntax". MySQL 5.7 Reference Manual. Oracle Corporation. Retrieved 2015-12-03.
स्रोत
- Pratt, Phillip J (2005), A Guide To SQL, Seventh Edition, Thomson Course Technology, ISBN 978-0-619-21674-0
- Shah, Nilesh (2005) [2002], Database Systems Using Oracle – A Simplified Guide to SQL and PL/SQL Second Edition (International ed.), Pearson Education International, ISBN 0-13-191180-5
- Yu, Clement T.; Meng, Weiyi (1998), Principles of Database Query Processing for Advanced Applications, Morgan Kaufmann, ISBN 978-1-55860-434-6, retrieved 2009-03-03