टेबल ए और बी के साथ उदाहरण:
A (parent) B (child)
============ =============
id | name pid | name
------------ -------------
1 | Alex 1 | Kate
2 | Bill 1 | Lia
3 | Cath 3 | Mary
4 | Dale NULL | Pan
5 | Evan
यदि आप माता-पिता और उनके बच्चों को ढूंढना चाहते हैं, तो आप एक INNER JOIN
करते हैं :
SELECT id, parent.name AS parent
, pid, child.name AS child
FROM
parent INNER JOIN child
ON parent.id = child.pid
नतीजा यह है कि parent
. का हर मैच की id
बाईं तालिका से और एक child
का pid
दूसरी तालिका से परिणाम में एक पंक्ति के रूप में दिखाई देगा:
+----+--------+------+-------+
| id | parent | pid | child |
+----+--------+------+-------+
| 1 | Alex | 1 | Kate |
| 1 | Alex | 1 | Lia |
| 3 | Cath | 3 | Mary |
+----+--------+------+-------+
अब, उपरोक्त बच्चों के बिना माता-पिता नहीं दिखाता है (क्योंकि उनकी आईडी का बच्चे की आईडी में मेल नहीं है, तो आप क्या करते हैं? आप इसके बजाय एक बाहरी जुड़ाव करते हैं। तीन प्रकार के बाहरी जोड़ होते हैं, बाएँ, दाएँ और पूर्ण बाहरी जुड़ाव। हमें बाईं ओर की आवश्यकता है क्योंकि हम बाईं तालिका (पैरेंट) से "अतिरिक्त" पंक्तियाँ चाहते हैं:
SELECT id, parent.name AS parent
, pid, child.name AS child
FROM
parent LEFT JOIN child
ON parent.id = child.pid
परिणाम यह है कि पिछले मैचों के अलावा, सभी माता-पिता जिनका कोई मेल नहीं है (पढ़ें:कोई बच्चा नहीं है) भी दिखाया गया है:
+----+--------+------+-------+
| id | parent | pid | child |
+----+--------+------+-------+
| 1 | Alex | 1 | Kate |
| 1 | Alex | 1 | Lia |
| 3 | Cath | 3 | Mary |
| 2 | Bill | NULL | NULL |
| 4 | Dale | NULL | NULL |
| 5 | Evan | NULL | NULL |
+----+--------+------+-------+
वे सभी NULL
कहाँ थे? से आते हैं? ठीक है, MySQL (या कोई अन्य RDBMS जो आप उपयोग कर सकते हैं) को पता नहीं होगा कि वहाँ क्या रखा जाए क्योंकि इन माता-पिता का कोई मेल नहीं है (बच्चा), इसलिए कोई pid
नहीं है न ही child.name
उन माता-पिता के साथ मिलान करने के लिए। तो, यह NULL
. नामक इस विशेष गैर-मान को रखता है .
मेरा कहना है कि ये NULLs
LEFT OUTER JOIN
. के दौरान (परिणाम सेट में) बनाए जाते हैं .
इसलिए, यदि हम केवल उन माता-पिता को दिखाना चाहते हैं जिनके बच्चे नहीं हैं, तो हम एक WHERE child.pid IS NULL
जोड़ सकते हैं। LEFT JOIN
. के लिए ऊपर। WHERE
JOIN
. के बाद क्लॉज का मूल्यांकन (चेक) किया जाता है पूरा हो गया है। तो, उपरोक्त परिणाम से यह स्पष्ट है कि केवल अंतिम तीन पंक्तियाँ जहाँ pid
NULL दिखाया जाएगा:
SELECT id, parent.name AS parent
, pid, child.name AS child
FROM
parent LEFT JOIN child
ON parent.id = child.pid
WHERE child.pid IS NULL
परिणाम:
+----+--------+------+-------+
| id | parent | pid | child |
+----+--------+------+-------+
| 2 | Bill | NULL | NULL |
| 4 | Dale | NULL | NULL |
| 5 | Evan | NULL | NULL |
+----+--------+------+-------+
अब, क्या होता है यदि हम उस IS NULL
. को स्थानांतरित करते हैं WHERE
. से चेक करें शामिल होने के लिए ON
खंड?
SELECT id, parent.name AS parent
, pid, child.name AS child
FROM
parent LEFT JOIN child
ON parent.id = child.pid
AND child.pid IS NULL
इस मामले में डेटाबेस इन शर्तों से मेल खाने वाली दो तालिकाओं से पंक्तियों को खोजने का प्रयास करता है। यानी, पंक्तियाँ जहाँ parent.id = child.pid
और child.pid IN NULL
. लेकिन उसे ऐसा कोई मेल नहीं मिल सकता है क्योंकि कोई child.pid
. नहीं है कुछ (1, 2, 3, 4 या 5) के बराबर हो सकता है और एक ही समय में NULL हो सकता है!
तो, शर्त:
ON parent.id = child.pid
AND child.pid IS NULL
के बराबर है:
ON 1 = 0
जो हमेशा False
होता है ।
तो, यह बाईं तालिका से सभी पंक्तियों को क्यों लौटाता है? क्योंकि यह लेफ्ट जॉइन है! और लेफ्ट जॉइन रिटर्न पंक्तियां जो मेल खाती हैं (इस मामले में कोई नहीं) और साथ ही बाएं तालिका से पंक्तियाँ जो मेल नहीं खाती हैं चेक (इस मामले में सभी ):
+----+--------+------+-------+
| id | parent | pid | child |
+----+--------+------+-------+
| 1 | Alex | NULL | NULL |
| 2 | Bill | NULL | NULL |
| 3 | Cath | NULL | NULL |
| 4 | Dale | NULL | NULL |
| 5 | Evan | NULL | NULL |
+----+--------+------+-------+
मुझे आशा है कि उपरोक्त स्पष्टीकरण स्पष्ट है।
सिडेनोट (सीधे आपके प्रश्न से संबंधित नहीं):पृथ्वी पर क्यों नहीं Pan
हमारे किसी भी जॉइन में नहीं दिखा? क्योंकि उसका pid
है NULL
और SQL के तर्क (सामान्य नहीं) में NULL किसी भी चीज़ के बराबर नहीं है, इसलिए यह किसी भी मूल आईडी (जो 1,2,3,4 और 5 हैं) से मेल नहीं खा सकता है। यहां तक कि अगर वहाँ एक NULL था, तब भी यह मेल नहीं खाएगा क्योंकि NULL
कुछ भी बराबर नहीं है, यहां तक कि NULL
भी नहीं स्वयं (यह वास्तव में एक बहुत ही अजीब तर्क है!) इसलिए हम विशेष चेक का उपयोग करते हैं IS NULL
और नहीं एक = NULL
जाँच करें।
तो, होगा Pan
अगर हम RIGHT JOIN
करते हैं तो दिखाएँ ? हां यह होगा! क्योंकि एक राइट जॉइन उन सभी परिणामों को दिखाएगा जो मेल खाते हैं (पहला INNER JOIN हमने किया था) साथ ही राइट टेबल की सभी पंक्तियाँ जो मेल नहीं खातीं (जो हमारे मामले में एक है, (NULL, 'Pan')
पंक्ति।
SELECT id, parent.name AS parent
, pid, child.name AS child
FROM
parent RIGHT JOIN child
ON parent.id = child.pid
परिणाम:
+------+--------+------+-------+
| id | parent | pid | child |
+---------------+------+-------+
| 1 | Alex | 1 | Kate |
| 1 | Alex | 1 | Lia |
| 3 | Cath | 3 | Mary |
| NULL | NULL | NULL | Pan |
+------+--------+------+-------+
दुर्भाग्य से, MySQL में FULL JOIN
नहीं है . आप इसे अन्य RDBMS में आज़मा सकते हैं, और यह दिखाएगा:
+------+--------+------+-------+
| id | parent | pid | child |
+------+--------+------+-------+
| 1 | Alex | 1 | Kate |
| 1 | Alex | 1 | Lia |
| 3 | Cath | 3 | Mary |
| 2 | Bill | NULL | NULL |
| 4 | Dale | NULL | NULL |
| 5 | Evan | NULL | NULL |
| NULL | NULL | NULL | Pan |
+------+--------+------+-------+