2009-04-15 10 views
46

Tengo una consulta de MySQL que une dos tablasMySQL Ingreso en los que no existe

  • votantes
  • Hogares se unen en voters.household_id y household.id

    Ahora lo que tengo que hacer es modificarlo donde la tabla de votantes se une a una tercera tabla llamada eliminación, a lo largo de voter.id y eliminación.voter_id, cualquiera que sea la captura es que quiero excluir cualquier registro en la tabla de votantes que tenga un registro correspondiente en la eliminación mesa. ¿Cómo hago una consulta para hacer esto?

esta es mi consulta actual

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 

Respuesta

122

probablemente me utilizo Únete a una izquierda, que devolverá filas incluso si no hay ninguna coincidencia, y entonces usted puede seleccionar sólo las filas que no coinciden por buscando NULLs.

Por lo tanto, algo así como:

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

si eso es más o menos eficiente que usar una sub consulta depende de optimización, índices, si su posible tener más de una eliminación por votante, etc.

+8

+1 vuelve más rápido que las consultas secundarias – ravi404

+1

+1 mucho más rápido en alta carga y luego subconsultas + si U puede hacer uniones en lugar de subconsultas, simplemente hacer UNIONES es mucho más simple para el analizador. Otro ejemplo útil, U puede querer obtener un resultado si hay algunas filas en la tabla de la derecha o si no hay ninguna: 'SELECT V. * FROM voter V LEFT JOIN eliminación E ON V.id = E.voter_id O E .voter_id IS NULL' ex .: si U no desea almacenar todos los registros en la tabla correcta para cada fila de la izquierda. –

4

que haría uso de una 'existe donde no' - exactamente como usted sugiere en su título:

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 

Eso puede ser marginalmente más rápido que hacerlo a la izquierda unirse (por supuesto, en función de sus índices, cardinalidad de sus tablas, etc.), y es casi seguro mucho más que el uso de IN.

+0

Gracias por eso, fue definitivamente más rápido para mí. – spidie

15
+2

Conclusión de este artículo: "Es por eso que la mejor manera de buscar valores perdidos en MySQL es usando un LEFT JOIN/IS NULL o NOT IN en lugar de NOT EXISTS." – marcovtwout

+3

link only answer = malo – Andrew

+0

No relacionado, pero un marco Para mi eliminación (Laravel) genera la consulta NOT EXIST al hacer preguntas whereDoesntHave – Tebe

1

hay tres posibles maneras de hacer eso.

  1. Opción
 
     SELECT lt.* FROM table_left l 
     LEFT JOIN 
      table_right r 
     ON  rt.value = lt.value 
     WHERE rt.value IS NULL 
  1. Opción
 
     SELECT lt.* FROM table_left l 
     WHERE lt.value NOT IN 
     (
     SELECT value 
     FROM table_right r 
     ) 
  1. Opción
 
     SELECT lt.* FROM table_left l 
     WHERE NOT EXISTS 
     (
     SELECT NULL 
     FROM table_right r 
     WHERE rt.value = lt.value 
     ) 
Cuestiones relacionadas