web-dev-qa-db-fra.com

Rejoindre MySQL là où il n'y en a pas

J'ai une requête MySQL qui joint deux tables

  • Les électeurs
  • Les ménages qu'ils rejoignent sur électeurs.maison_id et ménage.id

    Maintenant, ce que je dois faire est de le modifier là où la table électorale est jointe à une troisième table appelée élimination, avec voter.id et élimination.voter_id, quelle que soit la difficulté, c'est que je veux exclure tous les enregistrements de la table électorale qui ont un enregistrement correspondant dans le tableau d'élimination. comment créer une requête pour ce faire?

c'est ma requête actuelle

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 
66
gsueagle2008

J'utiliserais probablement une jointure gauche, qui retournera des lignes même s'il n'y a pas de correspondance, puis vous pouvez sélectionner uniquement les lignes sans correspondance en vérifiant les valeurs NULL.

Donc, quelque chose comme:

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

Que ce soit plus ou moins efficace que l'utilisation d'une sous-requête dépend de l'optimisation, des index, de la possibilité d'avoir plus d'une élimination par électeur, etc.

159
NickZoic

J'utiliserais un "où n'existe pas" - exactement comme vous le suggérez dans votre titre:

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

Cela peut être légèrement plus rapide que de faire une jointure gauche (bien sûr, selon vos index, la cardinalité de vos tables, etc.), et est presque certainement beaucoup plus rapide que d'utiliser IN.

5
Ian Clelland

Il y a trois façons possibles de le faire.

  1. Option
 SELECT lt. * FROM table_left lt 
 LEFT JOIN 
 Table_right rt 
 ON rt.value = lt.value 
 OERE rt.value _ [IS NULL 
  1. Option
 SELECT lt. * FROM table_left lt 
 O l lt.value PAS DANS 
 (
 SELECT valeur 
 FROM table_right rt 
) 
  1. Option
 SELECT lt. * FROM table_left lt 
 OERE N'EXISTE PAS 
 (
 SELECT NULL 
 FROM table_right rt 
 WHERE rt.value = lt.value 
) 
3