EXCEPT
ऑपरेटर SQL सर्वर 2005 में शुरू की गई थी, लेकिन दोनों के बीच क्या अंतर है NOT IN
और EXCEPT
?
क्या यह भी ऐसा ही है? मैं एक उदाहरण के साथ एक सरल व्याख्या करना चाहूंगा।
EXCEPT
ऑपरेटर SQL सर्वर 2005 में शुरू की गई थी, लेकिन दोनों के बीच क्या अंतर है NOT IN
और EXCEPT
?
क्या यह भी ऐसा ही है? मैं एक उदाहरण के साथ एक सरल व्याख्या करना चाहूंगा।
जवाबों:
के बीच दो प्रमुख अंतर हैं EXCEPT
और NOT IN
।
EXCEPT
DISTINCT
बाएं हाथ की तालिका से उन मानों को फ़िल्टर करता है जो दाएँ हाथ की तालिका में नहीं दिखाई देते हैं। यह अनिवार्य रूप NOT EXISTS
से एक DISTINCT
खंड के साथ कर के रूप में ही है ।
यह दो तालिकाओं (या तालिकाओं से स्तंभों के सबसेट) की भी अपेक्षा करता है, जिसमें क्वेरी के बाएँ और दाएँ हाथ में समान स्तंभ हों
उदाहरण के लिए, आप ऐसा नहीं कर सकते:
SELECT ID, Name FROM TableA
EXCEPT
SELECT ID FROM TableB
इसके परिणामस्वरूप त्रुटि होगी:
UNION, INTERSECT या EXCEPT ऑपरेटर का उपयोग करके संयुक्त किए गए सभी प्रश्नों को उनकी लक्ष्य सूचियों में समान संख्या में भाव होने चाहिए।
NOT IN
DISTINCT
मानों के लिए फ़िल्टर नहीं करता है और बाएँ हाथ की तालिका से सभी मान लौटाता है जो दाएँ हाथ की तालिका में दिखाई नहीं देता है।
NOT IN
आवश्यकता है कि आप एक तालिका से एक स्तंभ की तुलना किसी अन्य तालिका या उपवर्ग से एक एकल स्तंभ से करें।
उदाहरण के लिए, यदि आपकी उपश्रेणी कई कॉलमों को वापस करने के लिए थी:
SELECT * FROM TableA AS nc
WHERE ID NOT IN (SELECT ID, Name FROM TableB AS ec)
आपको निम्न त्रुटि मिलेगी:
जब उपसीम को EXISTS के साथ पेश नहीं किया जाता है, तो केवल एक अभिव्यक्ति का चयन सूची में किया जा सकता है।
हालाँकि, यदि दाएं हाथ की तालिका में NULL
फ़िल्टर किए जा रहे मानों में शामिल है NOT IN
, तो एक खाली परिणाम सेट लौटाया जाता है, संभवतः अप्रत्याशित परिणाम देता है।
CREATE TABLE #NewCustomers (ID INT);
CREATE TABLE #ExistingCustomers (ID INT);
INSERT INTO #NewCustomers
( ID )
VALUES
(8), (9), (10), (1), (3), (8);
INSERT INTO #ExistingCustomers
( ID )
VALUES
( 1) , (2), (3), (4), (5);
-- EXCEPT filters for DISTINCT values
SELECT * FROM #NewCustomers AS nc
EXCEPT
SELECT * FROM #ExistingCustomers AS ec
-- NOT IN returns all values without filtering
SELECT * FROM #NewCustomers AS nc
WHERE ID NOT IN (SELECT ID FROM #ExistingCustomers AS ec)
उपरोक्त दो प्रश्नों से, EXCEPT
3 पंक्तियों को वापस करता है #NewCustomers
, 1 और 3 से मेल खाते हुए #ExistingCustomers
और 8 नकल करता है।
NOT IN
यह अलग फ़िल्टरिंग नहीं करता है और #NewCustomers
डुप्लिकेट 8 के साथ 4 पंक्तियों को लौटाता है ।
अब हम एक में जोड़ देते हैं तो NULL
करने के लिए #ExistingCustomers
टेबल, हम द्वारा दिया एक ही परिणाम देखने EXCEPT
, फिर भी NOT IN
एक खाली परिणाम सेट वापस आ जाएगी।
INSERT INTO #ExistingCustomers
( ID )
VALUES
( NULL );
-- With NULL values in the right-hand table, EXCEPT still returns the same results as above
SELECT * FROM #NewCustomers AS nc
EXCEPT
SELECT * FROM #ExistingCustomers AS ec
-- NOT IN now returns no results
SELECT * FROM #NewCustomers AS nc
WHERE ID NOT IN (SELECT ID FROM #ExistingCustomers AS ec)
DROP TABLE #NewCustomers;
DROP TABLE #ExistingCustomers;
इसके बजाय NOT IN
, आपको वास्तव में देखना चाहिए NOT EXISTS
और गेल शॉ के ब्लॉग पर दोनों के बीच अच्छी तुलना है ।
मार्क सिंकिनसन की उत्कृष्ट टिप्पणी के लिए एक लत:
नहीं की आवश्यकता है आप एक तालिका से एक स्तंभ की तुलना किसी अन्य तालिका या उपवर्ग से एक स्तंभ के साथ करें।
आप वास्तव में NOT IN
एक से अधिक कॉलम के साथ प्रदर्शन कर सकते हैं ।
उदाहरण के लिए यह पूरी तरह से कानूनी * SQL क्वेरी है:
SELECT E.first_name, E.last_name
FROM employees E
WHERE (E.first_name, E.last_name) NOT IN
(SELECT M.first_name, M.last_name FROM managers M)
जो वापस आ जाएगा first_name
और last_name
सभी लोग जो कर्मचारी हैं, लेकिन प्रबंधक भी नहीं हैं।
* - लेकिन निर्माण SQL सर्वर में अभी तक लागू नहीं हुआ है।
ऊपर का नोट विफल रहता है क्योंकि मुख्य क्वेरी और उपकुंजी में विधेय के बीच सहसंबंध होना चाहिए। यदि आप इसे छोड़ देते हैं तो आपको एक UNCORRELATED उपकुंजी मिल जाती है।
चयन करें * से तालिका के रूप में nc वहाँ नहीं है (चयन आईडी, तालिका से नाम के रूप में जहाँ nc.ID = ec.ID)
EXCEPT बेहतर है और IS NULL / IS NOT NULL का उपयोग किए बिना किसी भी अशक्त पंक्तियों को संभाल लेगा।