MySQL Join Wo not exists
-
09-09-2019 - |
Frage
Ich habe eine MySQL-Abfrage, die zwei Tabellen
schließt sich- Die Wähler
-
Die Haushalte sie kommen auf voters.household_id und household.id
Nun, was ich tun müssen, um sie zu ändern, wo die Wähler Tabelle in eine dritte Tabelle namens Eliminierung entlang voter.id und elimination.voter_id verbunden ist, wie auch immer der Haken ist, dass ich alle Datensätze in der Wähler ausschließen möchten Tabelle, die einen entsprechenden Eintrag in der Eliminations Tabelle. Wie kann ich eine Abfrage Handwerk, dies zu tun?
Das ist meine aktuelle Abfrage
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
Lösung
ich wahrscheinlich ein LEFT JOIN verwenden würde, die Reihen selbst zurück, wenn es keine Übereinstimmung gibt, und dann können Sie nur die Zeilen ohne Spiel auswählen, indem Sie für NULL-Werte zu überprüfen.
Also, so etwas wie:
SELECT V.*
FROM voter V LEFT JOIN elimination E ON V.id = E.voter_id
WHERE E.voter_id IS NULL
Ob das mehr oder weniger effizient als eine Unterabfrage ist abhängig von Optimierung, Indizes, ob ihre möglich, mehr als eine Eliminierung pro Wähler zu haben, etc.
Andere Tipps
Ich würde verwenden eine ‚wo nicht existiert‘ - genau so, wie Sie in Ihrem Titel vorschlagen:
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
Das mag geringfügig schneller als eine linke tut kommen (natürlich abhängig von Ihrer Indizes Mächtigkeit Ihrer Tabellen, usw.), und ist mit ziemlicher Sicherheit viel schneller als bei der Verwendung.
Es gibt drei Möglichkeiten, das zu tun.
- Option
SELECT lt.* FROM table_left lt LEFT JOIN table_right rt ON rt.value = lt.value WHERE rt.value IS NULL
- Option
SELECT lt.* FROM table_left lt WHERE lt.value NOT IN ( SELECT value FROM table_right rt )
- Option
SELECT lt.* FROM table_left lt WHERE NOT EXISTS ( SELECT NULL FROM table_right rt WHERE rt.value = lt.value )