अपवाद ऑपरेटर बनाम में नहीं


19

EXCEPTऑपरेटर SQL सर्वर 2005 में शुरू की गई थी, लेकिन दोनों के बीच क्या अंतर है NOT INऔर EXCEPT?

क्या यह भी ऐसा ही है? मैं एक उदाहरण के साथ एक सरल व्याख्या करना चाहूंगा।

जवाबों:


29

के बीच दो प्रमुख अंतर हैं EXCEPTऔर NOT IN

के सिवाय

EXCEPTDISTINCTबाएं हाथ की तालिका से उन मानों को फ़िल्टर करता है जो दाएँ हाथ की तालिका में नहीं दिखाई देते हैं। यह अनिवार्य रूप NOT EXISTSसे एक DISTINCTखंड के साथ कर के रूप में ही है ।

यह दो तालिकाओं (या तालिकाओं से स्तंभों के सबसेट) की भी अपेक्षा करता है, जिसमें क्वेरी के बाएँ और दाएँ हाथ में समान स्तंभ हों

उदाहरण के लिए, आप ऐसा नहीं कर सकते:

SELECT ID, Name FROM TableA
EXCEPT
SELECT ID FROM TableB

इसके परिणामस्वरूप त्रुटि होगी:

UNION, INTERSECT या EXCEPT ऑपरेटर का उपयोग करके संयुक्त किए गए सभी प्रश्नों को उनकी लक्ष्य सूचियों में समान संख्या में भाव होने चाहिए।

अंदर नही

NOT INDISTINCTमानों के लिए फ़िल्टर नहीं करता है और बाएँ हाथ की तालिका से सभी मान लौटाता है जो दाएँ हाथ की तालिका में दिखाई नहीं देता है।

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)

उपरोक्त दो प्रश्नों से, EXCEPT3 पंक्तियों को वापस करता है #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और गेल शॉ के ब्लॉग पर दोनों के बीच अच्छी तुलना है ।


यदि उपयुक्त हो तो क्या EXCEPT सूचकांकों का उपयोग करेगा?
जॉनऑपिनकर

1

मार्क सिंकिनसन की उत्कृष्ट टिप्पणी के लिए एक लत:

नहीं की आवश्यकता है आप एक तालिका से एक स्तंभ की तुलना किसी अन्य तालिका या उपवर्ग से एक स्तंभ के साथ करें।

आप वास्तव में 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 सर्वर में अभी तक लागू नहीं हुआ है।


-2

ऊपर का नोट विफल रहता है क्योंकि मुख्य क्वेरी और उपकुंजी में विधेय के बीच सहसंबंध होना चाहिए। यदि आप इसे छोड़ देते हैं तो आपको एक UNCORRELATED उपकुंजी मिल जाती है।

चयन करें * से तालिका के रूप में nc वहाँ नहीं है (चयन आईडी, तालिका से नाम के रूप में जहाँ nc.ID = ec.ID)

EXCEPT बेहतर है और IS NULL / IS NOT NULL का उपयोग किए बिना किसी भी अशक्त पंक्तियों को संभाल लेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.