पहले थोड़ा सिद्धांत:नल (एसक्यूएल)
उपरोक्त लिंक से हमारे लिए सबसे महत्वपूर्ण भाग:
NULL और तीन-मूल्यवान तर्क (3VL) के साथ तुलना
चूंकि नल किसी भी डेटा डोमेन का सदस्य नहीं है, इसलिए इसे "मान" नहीं माना जाता है, बल्कि एक मार्कर (या प्लेसहोल्डर) माना जाता है जो मूल्य के अभाव को दर्शाता है। इस वजह से, नल के साथ तुलना का परिणाम कभी भी सही या गलत नहीं हो सकता है, लेकिन हमेशा तीसरे तार्किक परिणाम में, अज्ञात होता है। [8] नीचे दिए गए व्यंजक का तार्किक परिणाम, जो मान 10 की तुलना शून्य से करता है, अज्ञात है:
SELECT 10 = NULL -- Results in Unknown
ताकि दोनों तुलनाएं:x = NULL और x <> NULL NULL (अज्ञात) का मूल्यांकन करता है।
SQL तीन तार्किक परिणामों को लागू करता है, इसलिए SQL कार्यान्वयन को एक विशेष तीन-मूल्यवान तर्क (3VL) के लिए प्रदान करना चाहिए। एसक्यूएल तीन-मूल्यवान तर्क को नियंत्रित करने वाले नियम नीचे दी गई तालिकाओं में दिखाए गए हैं (पी और क्यू तार्किक राज्यों का प्रतिनिधित्व करते हैं) जो उनके निहितार्थ की परिभाषा में भिन्न है, हालांकि SQL ऐसे किसी भी ऑपरेशन को परिभाषित नहीं करता है)।
+---------+-------------+-------------+-------------+-----------+--------+
| p | q | p OR q | p AND q | p = q |p != q |
+---------+-------------+-------------+-------------+-----------+--------+
| True | True | True | True | True | False |
| True | False | True | False | False | True |
| True | Unknown | True | Unknown | Unknown | Unknown|
| False | True | True | False | False | True |
| False | False | False | False | True | False |
| False | Unknown | Unknown | False | Unknown | Unknown|
| Unknown | True | True | Unknown | Unknown | Unknown|
| Unknown | False | Unknown | False | Unknown | Unknown|
| Unknown | Unknown | Unknown | Unknown | Unknown | Unknown|
+---------+-------------+-------------+-------------+-----------+--------+
<ब्लॉकक्वॉट> WHERE क्लॉज में अज्ञात का प्रभाव
SQL तीन-मूल्यवान तर्क DML कथनों और प्रश्नों की तुलना में डेटा हेरफेर भाषा (DML) में सामने आया है। WHERE क्लॉज के कारण DML स्टेटमेंट केवल उन्हीं पंक्तियों पर कार्य करता है, जिसके लिए विधेय का मूल्यांकन True होता है।
तो संक्षेप में:WHERE क्लॉज NULL को FALSE मानता है
अब कृपया एक सरल मामले पर विचार करें:
SELECT * FROM T1;
| X |
|--------|
| 1 |
| (null) |
और एक प्रश्न:
SELECT * FROM t1 WHERE x IN (1, NULL);
ऊपर दी गई क्वेरी इसके लिए एक शॉर्टलैंड है:
SELECT * FROM t1
WHERE x = 1
OR x = NULL
तालिका से दूसरी पंक्ति के लिए t ( x =NULL) यह स्थिति कुछ इस तरह दिखती है:
WHERE NULL = 1
OR NULL = NULL
तो पंक्ति के लिए यह शर्त x=NULL NULL का मूल्यांकन करता है क्योंकि NULL=1 NULL है, NULL=NULL NULL है, और NULL OR NULL NULL भी है (कृपया ऊपर दी गई तालिका 3VL देखें)।
अब अधिक जिज्ञासु मामले पर विचार करें:
SELECT * FROM t1 WHERE x NOT IN (1, NULL);
यह खंड x NOT IN (1, NULL) NOT ( x IN (1, NULL) )
तो यह इसके बराबर भी है:
NOT (
x = 1
OR
x = NULL
)
और डी मॉर्गन के नियमों के अनुसार यह इसके बराबर है:
NOT ( x = 1 ) AND NOT ( x = NULL )
और (यदि हम NOT x = y . को प्रतिस्थापित करते हैं x <> y . के साथ ) यह इसके बराबर भी है:
x <> 1 AND x <> NULL
कृपया अंतिम स्थिति को ध्यान से देखें:
WHERE
x <> 1 AND x <> NULL
हम x <> NULL . से अधिक जानते हैं हमेशा NULL का मूल्यांकन करता है। हम उपरोक्त 3VL तालिका से यह भी जानते हैं कि true AND NULL both दोनों NULL और false AND NULL है FALSE का मूल्यांकन करता है, इसलिए पूरी स्थिति का मूल्यांकन हमेशा FALSE या NULL में किया जाता है, लेकिन यह कभी भी TRUE का मूल्यांकन नहीं करता है।
इसलिए इस शर्त के साथ एक प्रश्न:
SELECT .....
WHERE x NOT IN ( NULL, whatever)
हमेशा खाली परिणाम देता है
और अब आपकी क्वेरी, जो उत्सुक भी है:
SELECT * FROM t1
WHERE (id, val) NOT IN (select id, val from data2);
जिसे (निरंतर मानों का उपयोग करके) फिर से लिखा जा सकता है:
SELECT * FROM t1
WHERE (id, val) NOT IN (
(1, null),
(2, 2 )
)
यह क्वेरी तथाकथित पंक्ति मान अभिव्यक्ति का उपयोग कर रही है
मूल रूप से इस तरह से पंक्ति मान एक्सप्रेसिन का उपयोग करने वाली एक शर्त
(a, b) = (x, y)
इसके बराबर है:
a = x AND b = y
इसलिए उपरोक्त क्वेरी को इसमें फिर से लिखा जा सकता है:
SELECT * FROM t1
WHERE NOT (
id = 1 AND val = NULL
OR
id = 2 AND val = 2
)
डी मॉर्गन के नियमों के अनुसार यह समान है:
SELECT * FROM t1
WHERE
NOT ( id = 1 AND val = NULL )
AND
NOT ( id = 2 AND val = 2 )
और आगे:
SELECT * FROM t1
WHERE
( id <> 1 OR val <> NULL )
AND
( id <> 2 OR val <> 2 )
पहले भाग के बाद से ( id <> 1 OR val <> NULL ) शर्त का मूल्यांकन केवल उस स्थिति में होता है जब id <> 1 (कृपया ऊपर 3VL तालिका देखें), इस शर्त को सरल बनाया जा सकता है:
SELECT * FROM t1
WHERE
( id <> 1 )
AND
( id <> 2 OR val <> 2 )
और आगे (डी मॉर्गन के नियमों के अनुसार):
SELECT * FROM t1
WHERE
id <> 1 AND id <> 2
OR
id <> 1 AND val <> 2
तो न तो (1,1) न ही (2,2) स्रोत से data1 इन शर्तों का पालन करें।