किसी अन्य तालिका में बिना मिलान प्रविष्टि वाली पंक्तियों का चयन कैसे करें?


323

मैं एक डेटाबेस एप्लिकेशन पर कुछ रखरखाव का काम कर रहा हूं और मुझे पता चला है कि, खुशियों का आनंद, भले ही एक टेबल से मानों का उपयोग विदेशी कुंजी की शैली में किया जा रहा हो, मेजों पर कोई विदेशी कुंजी बाधा नहीं है।

मैं इन स्तंभों पर FK बाधाओं को जोड़ने की कोशिश कर रहा हूं, लेकिन मुझे यह पता चल रहा है, क्योंकि पिछली त्रुटियों से तालिकाओं में पहले से ही खराब डेटा का एक पूरा भार है, जिसे भोलेपन से ठीक किया गया है, मुझे उन पंक्तियों को खोजने की आवश्यकता है जो नहीं करते हैं दूसरी तालिका तक मिलान करें और फिर उन्हें हटाएं।

मैंने वेब पर इस तरह के क्वेरी के कुछ उदाहरण पाए हैं, लेकिन वे सभी स्पष्टीकरण के बजाय उदाहरण प्रदान करते हैं, और मुझे समझ नहीं आता कि वे क्यों काम करते हैं।

क्या कोई मुझे समझा सकता है कि एक ऐसी क्वेरी कैसे बनाई जाए, जो किसी अन्य तालिका में बिना किसी मिलान के सभी पंक्तियों को लौटाए, और यह क्या कर रही है, ताकि मैं इन प्रश्नों को स्वयं बना सकूं, बजाय इसके कि इस गड़बड़ में हर तालिका के लिए SO पर आने के बजाय कोई FK बाधाओं?

जवाबों:


613

यहाँ एक सरल प्रश्न है:

SELECT t1.ID
FROM Table1 t1
    LEFT JOIN Table2 t2 ON t1.ID = t2.ID
WHERE t2.ID IS NULL

मुख्य बिंदु हैं:

  1. LEFT JOINप्रयोग किया जाता है; इससे सभी पंक्तियों को वापस कर दिया जाएगा Table1, भले ही इसमें एक मिलान पंक्ति हो या न हो Table2

  2. WHERE t2.ID IS NULLखंड; यह केवल उन पंक्तियों को लौटाए गए परिणामों को प्रतिबंधित करेगा जहां से लौटी आईडी Table2शून्य है - दूसरे शब्दों में उस विशेष आईडी के लिए कोई रिकॉर्ड नहींTable2 है Table1Table2.IDउन सभी रिकॉर्डों के लिए NULL के रूप में लौटाया जाएगा Table1जहाँ से ID का मिलान नहीं किया गया है Table2


4
विफल रहता है एक आईडी शून्य है
माइकल

168
@ मिचेल - यदि NULLआपके स्कीमा में एक आईडी मान्य है, तो आपको बड़ी समस्याएं हो सकती हैं, क्या आप सहमत नहीं होंगे? :)
rinogo

1
क्या यह काम तब भी होगा जब टेबल 1 में अधिक रिकॉर्ड हो तो टेबल 2? यदि टेबल 1 में 100 रिकॉर्ड हैं और टेबल 2 में 200 रिकॉर्ड हैं (100 जो मैच / जॉइन करते हैं और 100 जो मैच / जॉइन नहीं करते हैं) तो क्या हम सभी रिकॉर्ड वापस कर देंगे?
जुआन वेलेज़

1
मैं अक्सर एक सबक्वेरी / इनलाइन व्यू के रूप में लेफ्ट जॉइन को लपेटना पसंद करता हूं ताकि यह सुनिश्चित हो सके कि WHERE क्लॉज और LEFT JOIN के बीच कोई इंटरप्ले न हो।
एंड्रयू वोल्फ

1
@Jas कुंजी का उत्तर 1, पहली तालिका की सभी पंक्तियाँ, यहां तक ​​कि मिलान न करने वाले t1.ID = t2.ID बाईं स्थिति में शामिल नहीं हैं। यदि आप पहली पंक्ति को बदल देते हैं SELECT t1.ID, t2.IDऔर WHERE लाइन को हटा देते हैं तो आपको बेहतर विचार मिलेगा कि यह कैसे काम करता है।
पीटर लैबो

97

मैं EXISTSअभिव्यक्ति का उपयोग करूंगा क्योंकि यह अधिक शक्तिशाली है, आप अधिक सटीक रूप से उन पंक्तियों का चयन कर सकते LEFT JOINहैं जिन्हें आप शामिल करना चाहते हैं, यदि आपको इसमें शामिल होने वाली तालिका में सब कुछ लेना है। इसकी दक्षता संभवतः उतनी ही है जितनी कि LEFT JOINअशक्त परीक्षण के मामले में ।

SELECT t1.ID
FROM Table1 t1
WHERE NOT EXISTS (SELECT t2.ID FROM Table2 t2 WHERE t1.ID = t2.ID)

सर्वश्रेष्ठ निष्पादन के लिए क्वेरी ऑप्टिमाइज़र द्वारा इस सरल को आसानी से नियंत्रित किया जाता है।
एंड्रयू वोल्फ

2
हां, इसका मुख्य लाभ EXISTSइसकी परिवर्तनशीलता है।
ओन्ड्रेज बोजेक

1
सरल, सुरुचिपूर्ण और इसने मेरी समस्या हल कर दी! अच्छा है!
माइकमैटी

2
वास्तव में 7 सेकंड से 200ms तक की एक क्वेरी की गति कम कर दी ... (तुलना में WHERE t2.id IS NULL) धन्यवाद।
मोती कोर

4
@ MotiKorets का मतलब है आपने गति बढ़ाई :)
Ondrej Bozek

14
SELECT id FROM table1 WHERE foreign_key_id_column NOT IN (SELECT id FROM table2)

तालिका 1 में एक स्तंभ है जिसे आप विदेशी कुंजी बाधा में जोड़ना चाहते हैं, लेकिन तालिका 2 में दिए गए foreign_key_id_columnसभी मान मेल नहीं खाते हैं id

  1. प्रारंभिक चयन तालिका 1 से idएस को सूचीबद्ध करता है । ये वे पंक्तियाँ होंगी जिन्हें हम हटाना चाहते हैं।
  2. NOT INमें खंड जहां बयान केवल पंक्तियों को क्वेरी जहां में मान सीमित foreign_key_id_columnतालिका की सूची में नहीं है 2id रों।
  3. SELECTकोष्ठक में बयान सभी की एक सूची मिल जाएगा idकि तालिका 2 में हैं।

@ zb226: आपके लिंक INका शाब्दिक मूल्यों की सूची के साथ क्लॉज की सीमा के साथ क्या करना है । यह INउप-क्वेरी के परिणाम के साथ एक क्लॉज का उपयोग करने पर लागू नहीं होता है । उस सवाल का स्वीकृत जवाब वास्तव में एक उप-क्वेरी का उपयोग करके समस्या को हल करता है। (शाब्दिक मूल्यों की एक बड़ी सूची समस्याग्रस्त है क्योंकि यह एक विशाल SQL अभिव्यक्ति बनाता है। एक उप-क्वेरी ठीक काम करती है, भले ही परिणामी सूची बड़ी हो, SQL अभिव्यक्ति स्वयं छोटी होती है।)
कन्नन गोदान

@KananGoundan आप पूर्ण अधिकार हैं। त्रुटिपूर्ण टिप्पणी को वापस लेना।
zb226

8

T2वह तालिका कहाँ है जिसमें आप बाधा जोड़ रहे हैं:

SELECT *
FROM T2
WHERE constrained_field NOT
IN (
    SELECT DISTINCT t.constrained_field
    FROM T2 
    INNER JOIN T1 t
    USING ( constrained_field )
)

और परिणाम हटाएँ।


4

हमारे पास 2 टेबलें हैं (वेतन और कर्मचारी) यहां छवि विवरण दर्ज करें

अब मुझे कर्मचारी तालिका से वे रिकॉर्ड चाहिए जो वेतन में नहीं हैं। हम इसे 3 तरीकों से कर सकते हैं:

  1. इनर जॉइन का उपयोग करना
select * from employee
where id not in(select e.id from employee e inner join salary s on e.id=s.id)

यहां छवि विवरण दर्ज करें

  1. लेफ्ट आउटर जॉइन का उपयोग करना
select * from employee e 
left outer join salary s on e.id=s.id  where s.id is null

यहां छवि विवरण दर्ज करें

  1. पूर्ण जॉइन का उपयोग करना
select * from employee e
full outer join salary s on e.id=s.id where e.id not in(select id from salary)

यहां छवि विवरण दर्ज करें


2

इसी तरह के प्रश्न से यहां MySQL इनर जॉइन टू गेट रिकॉर्ड्स नॉट प्रेजेंटअदर टेबल, मुझे यह काम करने के लिए मिला

SELECT * FROM bigtable 
LEFT JOIN smalltable ON bigtable.id = smalltable.id 
WHERE smalltable.id IS NULL

smalltableवह जगह है जहां आपके पास रिकॉर्ड गायब हैं, bigtableजहां आपके पास सभी रिकॉर्ड हैं। क्वेरी उन सभी रिकॉर्डों को सूचीबद्ध करती है जो मौजूद नहीं हैं, smalltableलेकिन मौजूद हैं bigtable। आप idकिसी भी अन्य मिलान मापदंड से बदल सकते हैं।


0

आप नीचे दिखाए गए दृश्यों का विकल्प चुन सकते हैं :

CREATE VIEW AuthorizedUserProjectView AS select t1.username as username, t1.email as useremail, p.id as projectid, 
(select m.role from userproject m where m.projectid = p.id and m.userid = t1.id) as role 
FROM authorizeduser as t1, project as p

और फिर चयन या अद्यतन करने के लिए दृश्य पर काम करें:

select * from AuthorizedUserProjectView where projectid = 49

जो परिणाम देता है जैसा कि नीचे चित्र में दिखाया गया है अर्थात गैर-मिलान वाले कॉलम नल के लिए भरा गया है।

[Result of select on the view][1]

0

मुझे पता नहीं है कि कौन सा अनुकूलित है (@AdaTheDev की तुलना में), लेकिन यह तब और अधिक तेज़ हो जाता है जब मैं उपयोग करता हूं (मेरे लिए कम से कम)

SELECT id  FROM  table_1 EXCEPT SELECT DISTINCT (table1_id) table1_id FROM table_2

यदि आप कोई अन्य विशिष्ट विशेषता प्राप्त करना चाहते हैं, जिसका आप उपयोग कर सकते हैं:

SELECT COUNT(*) FROM table_1 where id in (SELECT id  FROM  table_1 EXCEPT SELECT DISTINCT (table1_id) table1_id FROM table_2);


-2

आप ऐसा कुछ कर सकते हैं

   SELECT IFNULL(`price`.`fPrice`,100) as fPrice,product.ProductId,ProductName 
          FROM `products` left join `price` ON 
          price.ProductId=product.ProductId AND (GeoFancingId=1 OR GeoFancingId 
          IS NULL) WHERE Status="Active" AND Delete="No"

-6

दोनों तालिका में बिना मिलान वाली पंक्तियों का चयन कैसे करें?

    [dbo] से चुनें * [EmppDetails] e
     राइट जॉइन [कर्मचारी]। [लिंग] d.Gid = d.Gid पर
    जहाँ ई। शून्य है

    संघ 
    [dbo] से चुनें * [EmppDetails] e
     बाएं हाथ से जुड़ें [कर्मचारी]। [लिंग] d.Gid = d.Gid पर
    जहां d.Gid अशक्त है

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