MySQL जॉइन कहां नहीं होता है


80

मेरे पास एक MySQL क्वेरी है जो दो तालिकाओं में मिलती है

  • मतदाता
  • परिवारों

वे पर voters.household_idऔर शामिल होते हैं household.id

अब मुझे जो करने की जरूरत है, उसे संशोधित करने के लिए जहां मतदाता तालिका को उन्मूलन नामक एक तीसरी तालिका में शामिल किया गया है, के साथ voter.idऔर elimination.voter_id। हालाँकि पकड़ यह है कि मैं मतदाता तालिका में किसी भी रिकॉर्ड को बाहर करना चाहता हूं, जिसका उन्मूलन तालिका में एक ही रिकॉर्ड है।

मैं इसे करने के लिए एक क्वेरी कैसे तैयार करूं?

यह मेरी वर्तमान क्वेरी है:

SELECT `voter`.`ID`, `voter`.`Last_Name`, `voter`.`First_Name`,
       `voter`.`Middle_Name`, `voter`.`Age`, `voter`.`Sex`,
       `voter`.`Party`, `voter`.`Demo`, `voter`.`PV`,
       `household`.`Address`, `household`.`City`, `household`.`Zip`
FROM (`voter`)
JOIN `household` ON `voter`.`House_ID`=`household`.`id`
WHERE `CT` = '5'
AND `Precnum` = 'CTY3'
AND  `Last_Name`  LIKE '%Cumbee%'
AND  `First_Name`  LIKE '%John%'
ORDER BY `Last_Name` ASC
LIMIT 30 

जवाबों:


191

मैं शायद एक का उपयोग करता हूं LEFT JOIN, जो कि कोई मैच नहीं होने पर भी पंक्तियों को वापस कर देगा, और फिर आप NULLएस के लिए जाँच करके बिना किसी मैच के केवल पंक्तियों का चयन कर सकते हैं ।

तो, कुछ इस तरह:

SELECT V.*
FROM voter V LEFT JOIN elimination E ON V.id = E.voter_id
WHERE E.voter_id IS NULL

चाहे वह उप-वर्ग का उपयोग करने की तुलना में अधिक या कम कुशल हो, अनुकूलन, अनुक्रमित पर निर्भर करता है, चाहे वह प्रति मतदाता एक से अधिक उन्मूलन के लिए संभव हो, आदि।


3
उच्च-लोड पर +1 बहुत तेज़ी से उप-क्वेरीज़ + अगर यू सब-क्वेरीज़ के बजाय जॉइन कर सकते हैं - तो बस जॉइन करें कि वे एनालाइज़र के लिए बहुत सरल हैं। एक और उपयोगी उदाहरण, यू परिणाम प्राप्त करना चाह सकता है अगर कोई सही तालिका में कुछ पंक्तियाँ हैं या कोई भी नहीं हैं: SELECT V.* FROM voter V LEFT JOIN elimination E ON V.id = E.voter_id OR E.voter_id IS NULLपूर्व: यदि आप बाईं ओर से प्रत्येक पंक्ति के लिए दाईं तालिका में सभी रिकॉर्ड संग्रहीत नहीं करना चाहते हैं।
आर्थर कुशमैन

1
आप इस क्वेरी को उन पंक्तियों को खोजने के लिए कैसे संशोधित करेंगे, जो मौजूद नहीं हैं E, जब हम जिस डेटासेट में होते हैं , उसमें क्या E.voter_idहो सकता NULLहै JOIN?
डैनी बेकेट

आपको कुछ सामान्य कॉलम या संबंधित मूल्य के साथ तालिकाओं को एक साथ जोड़ना होगा। लेकिन मुझे लगता है कि यह काम कर सकता है ( SELECT V.*, COUNT(E.*) AS `countE` FROM voter V LEFT JOIN elimination E ON V.id = E.voter_id WHERE countE = 0;
अप्राप्त

7

मैं 'जहाँ मौजूद नहीं हूँ' का उपयोग करता हूँ - जैसा कि आप अपने शीर्षक में सुझाते हैं:

SELECT `voter`.`ID`, `voter`.`Last_Name`, `voter`.`First_Name`,
       `voter`.`Middle_Name`, `voter`.`Age`, `voter`.`Sex`,
       `voter`.`Party`, `voter`.`Demo`, `voter`.`PV`,
       `household`.`Address`, `household`.`City`, `household`.`Zip`
FROM (`voter`)
JOIN `household` ON `voter`.`House_ID`=`household`.`id`
WHERE `CT` = '5'
AND `Precnum` = 'CTY3'
AND  `Last_Name`  LIKE '%Cumbee%'
AND  `First_Name`  LIKE '%John%'

AND NOT EXISTS (
  SELECT * FROM `elimination`
   WHERE `elimination`.`voter_id` = `voter`.`ID`
)

ORDER BY `Last_Name` ASC
LIMIT 30

हो सकता है कि लेफ्ट जॉइन करने से थोड़ा ज्यादा तेज हो (बेशक, आपके इंडेक्स, आपके टेबल की कार्डिनैलिटी आदि के आधार पर), और IN का उपयोग करने की तुलना में लगभग निश्चित रूप से बहुत तेज है।


उसके लिए धन्यवाद - निश्चित रूप से मेरे लिए तेज था।
स्पाइडी

6

ऐसा करने के तीन संभावित तरीके हैं।

  1. विकल्प

    SELECT  lt.* FROM    table_left lt
    LEFT JOIN
        table_right rt
    ON      rt.value = lt.value
    WHERE   rt.value IS NULL
    
  2. विकल्प

    SELECT  lt.* FROM    table_left lt
    WHERE   lt.value NOT IN
    (
    SELECT  value
    FROM    table_right rt
    )
    
  3. विकल्प

    SELECT  lt.* FROM    table_left lt
    WHERE   NOT EXISTS
    (
    SELECT  NULL
    FROM    table_right rt
    WHERE   rt.value = lt.value
    )
    
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.