2008-09-29 20 views
23

मेरे पास दो टेबल हैं जो एक साथ जुड़े हुए हैं।मुझे ऐसे रिकॉर्ड कैसे मिलेंगे जो शामिल नहीं हैं?

select * from a,b where b.a_id = a.id 

ख में एक रिकॉर्ड है कि एक से रिकॉर्ड के सभी प्राप्त करने के लिए:

एक कई बी

आम तौर पर आप क्या करेंगे है।

मैं केवल उन रिकॉर्ड्स कैसे प्राप्त करूं जिनमें बी में कुछ भी नहीं है?

उत्तर

42
select * from a where id not in (select a_id from b) 

या इस धागे पर कुछ अन्य लोगों की तरह कहते हैं:

select a.* from a 
left outer join b on a.id = b.a_id 
where b.a_id is null 
2

चयन * से एक जहां आईडी में नहीं (ख से a_id चयन)

+1

यह बेहद महंगा होगा क्योंकि इंजन को पूरी तरह से सबक्वायरी उत्पन्न करना पड़ता है इससे पहले कि वह टुपल्स को खत्म कर सके। सामान्य रूप से एक अच्छा विचार नहीं है। – dland

10
select * from a 
left outer join b on a.id = b.a_id 
where b.a_id is null 
+0

मुझे लगता है कि यह बायां बाहरी हिस्सा 'इन' खंड से काफी बेहतर प्रदर्शन करेगा, जब तक कि क्वेरी ऑप्टिमाइज़र उन्हें समान व्यवहार न करे ... – Codewerks

+0

यह बहुत अधिक करता है। इसकी जांच - पड़ताल करें। –

+0

हाँ, दिलचस्प बात यह है कि क्वेरी प्लान में बाएं जुड़ने के लिए एक अतिरिक्त स्ट्रेप (फ़िल्टर) है और 'जहां इन' को 'सही एंटी अर्ध जॉइन' में हल किया गया है ... जो कुछ भी है ... – Codewerks

5

एक और दृष्टिकोण:

select * from a where not exists (select * from b where b.a_id = a.id) 

"मौजूद" दृष्टिकोण उपयोगी है यदि वें ere कुछ अन्य "कहां" खंड है जो आपको आंतरिक क्वेरी से संलग्न करने की आवश्यकता है।

1

आप शायद एक बहुत बेहतर प्रदर्शन प्राप्त होगा यदि आप एक बाहरी का उपयोग ('नहीं' में उपयोग करने की तुलना) में शामिल होने:

select * from a left outer join b on a.id = b.a_id where b.a_id is null; 
0

लेखन यह

select a.* from a left outer join b on a.id = b.id where b.id is null

आउच का एक अन्य तरीका, नाथन द्वारा पीटा :)

0

यह आपको इन क्लॉज में नल से बचाएगा, जो अप्रत्याशित व्यवहार कर सकता है।

चयन * से जहां में नहीं (ख से [एक id] का चयन करें जहां [एक id] नहीं अशक्त है)

+0

आप बेहतर उपयोग कर रहे हैं पहली जगह में एक अनुमान लगाने के बजाय बाएं बाहरी शामिल हों। – dland

+0

इस राय के लिए कोई कारण? –

3
SELECT id FROM a 
EXCEPT 
SELECT a_id FROM b; 
+0

ओरेकल में 'EXCEPT' कीवर्ड 'MINUS' है। – onedaywhen

0

मामले में से एक यह में शामिल होने में आईडी बहुत तेजी से, एक लेकिन जब हम डेटाबेस से रिकॉर्ड्स निकाल रहे हैं जिसमें लगभग 50 मिलियन रिकॉर्ड हैं और 4 और अधिक विदेशी कुंजी के कारण जुड़ते हैं, इसे करने में कुछ मिनट लगते हैं। अधिक तेज उपयोग करने के लिए जहां नहीं इस तरह की स्थिति में:

select a.* from a 
where a.id NOT IN(SELECT DISTINCT a_id FROM b where a_id IS NOT NULL) 
//And for more joins 
AND a.id NOT IN(SELECT DISTINCT a_id FROM c where a_id IS NOT NULL) 

मैं भी इस दृष्टिकोण के मामले में को हटाने हम कॉन्फ़िगर किया गया झरना को नष्ट नहीं है के लिए सिफारिश की जा सकता है। यह क्वेरी केवल कुछ सेकंड लेती है।

0

पहले दृष्टिकोण है

select a.* from a where a.id not in (select b.ida from b) 

दूसरा दृष्टिकोण

select a.* 
    from a left outer join b on a.id = b.ida 
    where b.ida is null 

पहले दृष्टिकोण है बहुत महंगा है। दूसरा दृष्टिकोण बेहतर है।

PostgreSql 9.4 के साथ, मैंने "क्वेरी समझाएं" फ़ंक्शन और लागत = 0.00 की लागत के रूप में पहली क्वेरी की।1982043603.32। इसके बजाय लागत की लागत के रूप में क्वेरी में शामिल होने = 45946.77..45946.78

उदाहरण के लिए, मैं सभी उत्पादों है कि कोई वाहनों के साथ संगत नहीं हैं के लिए खोज। मेरे पास 100k उत्पाद हैं और 1 मीटर से अधिक संगतताएं हैं I

select count(*) from product a left outer join compatible c on a.id=c.idprod where c.idprod is null 

जॉइन क्वेरी में 5 सेकंड बिताए गए, इसके बजाय सबक्वायरी संस्करण 3 मिनट के बाद कभी समाप्त नहीं हुआ है।

संबंधित मुद्दे