2010-06-25 15 views
6

Esto es lo que estoy tratando de lograr:Consulta SQL para encontrar filas que no están presentes en otras tablas

Tengo dos tablas, llámalas primera y segunda. Cada uno tiene una columna de ID. Pueden tener otras columnas, pero esas no son importantes. Tengo una tercera mesa, llamémosla tercera. Contiene dos columnas, ID y OTHERID. OTHERID hace referencia a entradas que pueden existir o no en las tablas primera y segunda.

Quiero consultar el tercero y buscar las filas que no tienen un valor de columna OTHERID que se encuentra en las tablas primera o segunda. El objetivo es eliminar esas filas de la tabla tercera.

Ejemplo:

primera tabla:

ID 
1 
2 
3 

segunda tabla:

ID 
6 
7 
8 

tercera tabla

ID | OTHERID 
21  1 
22  2 
23  3 
24  4 
25  5 
26  6 
27  7 
28  8 

En este caso, me gustaría recuperar el ID de terceros que no tienen ve una identificación correspondiente en la tabla primero o en la tabla segunda. Yo esperaría que volver los siguientes identificadores:

24 
25 

Lo que he intentado:

que he hecho algo esta opción para volver las entradas de tercera que no están en primera:

select t.* from third t where not exists (select * from first f where t.otherid = f.id); 

y esto va a conseguir que vuelva las filas siguientes:

ID | OTHERID 
24  4 
25  5 
26  6 
27  7 
28  8 

Del mismo modo, puedo obtener los que no están en segunda:

select t.* from third t where not exists (select * from second s where t.otherid = s.id); 

y conseguiré:

ID | OTHERID 
21  1 
22  2 
23  3 
24  4 
25  5 

Lo que no puedo hacer que mi cerebro lo de esta mañana es cómo combinar las dos consultas en conjunto para obtener la intersección entre los dos conjuntos de resultados , de modo que solo se devuelvan las filas con las ID 24 y 25. Esas serían dos filas que podría eliminar ya que son huérfanas.

¿Cómo solucionaría esto? Creo que estoy en el camino correcto, pero estoy dando vueltas en este momento sin avanzar.

Respuesta

14

Tal vez esto:

SELECT third.* 
FROM third 
LEFT JOIN first ON third.otherID = first.id 
LEFT JOIN second ON third.otherID = second.id 
WHERE first.id IS NULL AND second.id IS NULL 
+0

Gracias! Otra forma de resolverlo. – itsmatt

+0

@itsmatt: Realmente debería considerar usar este para un mejor rendimiento. El optimizador de MySQL5 es bastante cojo cuando se trata de subconsultas dependientes. –

7

sólo tiene que utilizar

select t.* 
from third t 
where 
     not exists (select * from first f where t.otherid = f.id) 
    and not exists (select * from second s where t.otherid = s.id) 
+0

@Lieven: Gracias. –

+0

Genial, gracias! Frustrante porque estaba cerca y no pude poner 2 y 2 juntos en esto. Chalk it to late Thursday :) – itsmatt

+2

Usar LEFT OUTER JOIN como lo sugirió Serty Oan sería mucho más eficiente. Las subconsultas dependientes, como las que se usan en las cláusulas 'no existe', tendrán que ejecutarse una vez por fila, mientras que una consulta IZQUIERDA EXTERIOR solo tendrá que escanearla una vez. (MySQL 5.x) –

4
SELECT t.ID 
FROM third t 
WHERE t.OTHERID NOT IN (
    SELECT ID 
    FROM first 

    UNION 

    SELECT ID 
    FROM second 
) 
+1

+1. Así es como lo escribiría, pero el 'no existe' debería funcionar mejor. (+1 en ese a por cierto :) –

+0

oh gracias. No sabía que NOT EXISTS funcionaba mejor. – SAGExSDX

+0

Gracias! Esto funcionó también. – itsmatt

Cuestiones relacionadas