2011-04-21 21 views
25

में मुझे एक क्वेरी बनाने की आवश्यकता है जो मुझे तालिका 1 में रिकॉर्ड दिखाएगा, लेकिन मेक-मॉडल-सीरियल नंबर संयोजन के आधार पर तालिका 2 में नहीं है।SQL सर्वर -

मुझे पता है कि 4 रिकॉर्ड अलग हैं, लेकिन मेरी क्वेरी हमेशा खाली हो जाती है।

SELECT * 
FROM Table1 WHERE MAKE+MODEL+[Serial Number] NOT IN 
(SELECT make+model+[serial number] FROM Table2) 

तालिका 1 में 5 रिकॉर्ड हैं।

जब मैं क्वेरी को IN पर बदलता हूं, तो मुझे 1 रिकॉर्ड मिलता है। NOT के साथ मैं क्या गलत कर रहा हूं?

+3

क्या आपके पास अपनी टेबल में कोई शून्य मान है? – tobias86

+0

शायद आपके डेटा को पोस्ट करने में मदद मिलेगी। वाक्यविन्यास ठीक दिखता है। (हालांकि psuedo-key थोड़े मजाकिया है) – Randy

उत्तर

35

यह the way NOT IN works की वजह से है।

इन सिर दर्द से बचने के लिए (और कई मामलों में एक तेजी से क्वेरी के लिए), मैं हमेशा मौजूद नहीं पसंद करते हैं:

SELECT * 
FROM Table1 t1 
WHERE NOT EXISTS (
    SELECT * 
    FROM Table2 t2 
    WHERE t1.MAKE = t2.MAKE 
    AND t1.MODEL = t2.MODEL 
    AND t1.[Serial Number] = t2.[serial number]); 
+0

यह है कि! धन्यवाद! –

+0

मेरे संपादन देखें (मैंने जो के अच्छे जवाब को पढ़ने के बाद अपना जवाब सुधार लिया) –

0

नल के लिए दाएं किनारे की जांच करने के लिए एक बाएं जॉइन का उपयोग करें।

SELECT a.Id 
FROM TableA a 
LEFT JOIN TableB on a.Id = b.Id 
WHERE b.Id IS NULL 

ऊपर TableA और TableB प्रत्येक के आईडी कॉलम के आधार पर मेल खाएंगे, और उसके बाद आप उन पंक्तियों को जहां बी पक्ष खाली है दे।

+0

यह आमतौर पर काम करता है, लेकिन आईएमओ समस्या का एक अच्छा सामान्य समाधान नहीं है क्योंकि इसके परिणामस्वरूप टेबलए के लिए डुप्लिकेट पंक्तियां हो सकती हैं यदि तालिका में भविष्य में शामिल होने के लिए कई पंक्तियां मौजूद हैं, और यदि बी आईडी एक शून्य कॉलम होता है, आप एक झूठी सकारात्मक प्राप्त कर सकते हैं। यह कई मामलों में इस समस्या का एक वैध समाधान है, हालांकि (डेटा के आधार पर) –

+0

@ डेवमार्क, हाँ, बहुत अच्छी चेतावनी, धन्यवाद। –

6

स्ट्रिंग्स को संयोजित करने के बजाए आप शायद अलग-अलग फ़ील्ड की तुलना करना बेहतर कर सकते हैं।

SELECT t1.* 
    FROM Table1 t1 
     LEFT JOIN Table2 t2 
      ON t1.MAKE = t2.MAKE 
       AND t1.MODEL = t2.MODEL 
       AND t1.[serial number] = t2.[serial number] 
    WHERE t2.MAKE IS NULL 
+0

बेहतर - जितनी तेजी से? :) –

+0

मुझे यह विचार पसंद है – tobias86

+0

@xrum: कॉलम पर इंडेक्स के साथ, मैं निश्चित रूप से ऐसा सोचूंगा। –

0

एक मुद्दा हो सकता है कि अगर या तो बनाने, मॉडल, या [सीरियल नंबर] अशक्त थे , मूल्य कभी वापस नहीं आएगा। क्योंकि शून्य मानों के साथ स्ट्रिंग कॉन्सटेनेशन हमेशा नल में होता है, और नल के साथ() में हमेशा कुछ भी नहीं लौटाएगा। इस के लिए उपाय ऐसे IsNull (बनाना, '') + IsNull (मॉडल, ''), आदि के रूप में एक ऑपरेटर का उपयोग करने के लिए है

1
SELECT [T1].* 
FROM [Table1] AS [T1] 
WHERE NOT EXISTS (SELECT 
    1 AS [C1] 
    FROM [Table2] AS [T2] 
    WHERE ([T2].[MAKE] = [T1].[MAKE]) AND 
     ([T2].[MODEL] = [T1].[MODEL]) AND 
     ([T2].[Serial Number] = [T1].[Serial Number]) 
); 
1
SELECT * FROM Table1 
WHERE MAKE+MODEL+[Serial Number] not in 
    (select make+model+[serial number] from Table2 
    WHERE make+model+[serial number] IS NOT NULL) 

वह मेरे लिए काम किया, जहां make+model+[serial number] एक क्षेत्र का नाम था