Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

शामिल होने की शर्तों पर IS NULL या IS NOT NULL का उपयोग करना - सिद्धांत प्रश्न

टेबल ए और बी के साथ उदाहरण:

 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   |
+------+--------+------+-------+


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. सीएसवी फ़ाइल के लिए एक ही समय में अल्पविराम और दोहरे उद्धरण से कैसे बचें?

  2. IN खंड के लिए पैरामीटर के साथ Oracle संग्रहीत कार्यविधि

  3. जावा में उपयोग में ओरेकल की वापसी (जेडीबीसी, तैयार वक्तव्य)

  4. oracle sql में ज्वाइन कीवर्ड और इनर जॉइन कीवर्ड में क्या अंतर है?

  5. Oracle में पैकेज के अंदर एक प्रक्रिया कैसे बनाएं