2011-09-29 12 views
39

Estoy tratando de encontrar las filas que están en una tabla pero no en otra, ambas tablas están en bases de datos diferentes y también tienen diferentes nombres de columna en la columna que estoy usando para hacer coincidir .Seleccione de una tabla donde no esté en otra

Tengo a continuación una consulta, código, y creo que probablemente funciona pero es demasiado lento:

SELECT `pm`.`id` 
FROM `R2R`.`partmaster` `pm` 
WHERE NOT EXISTS (
    SELECT * 
    FROM `wpsapi4`.`product_details` `pd` 
    WHERE `pm`.`id` = `pd`.`part_num` 
) 

lo que la consulta está tratando de hacer de la siguiente manera:

seleccionar todas las ID de la base de datos R2R.partmaster que no están en la base de datos wpsapi4.product_details. Las columnas que estoy buscando son partmaster.id & product_details.part_num

+0

Para mí existe/no existe es la mejor manera ya que expresar quiere claramente que desea obtener. Pero parece ser la forma más lenta (en MySQL). Comprueba esto: http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/ – DavidEG

Respuesta

64

Ampliando Sjoerd anti-unes, también se puede utilizar la fácil de entender SELECT WHERE X NOT IN (SELECT) patrón.

SELECT pm.id FROM r2r.partmaster pm 
WHERE pm.id NOT IN (SELECT pd.part_num FROM wpsapi4.product_details pd) 

Tenga en cuenta que sólo tendrá que utilizar ` acentos abiertos en palabras reservadas, con nombres tales espacios y, no con nombres de columna normales.

En MySQL 5+ este tipo de consulta se ejecuta bastante rápido.
En MySQL 3/4 es lento.

asegurarse de que tiene índices en los campos en cuestión
Tienes que un índice en pm.id, pd.part_num.

+1

Gracias por su respuesta, no funcionó lo suficientemente rápido, pero la consulta es buena, pero no en mi base de datos. He resuelto otra solución pero stackOverflow no me deja publicar hasta 3 horas. – Drahcir

+1

Sólo un aviso que una consulta similar como la anterior tomó aproximadamente ~ 10 minutos en MySQL 5.1.73a. Cuando actualicé a MySQL 5.6.22, tardé aproximadamente 456ms. –

+0

Esto funciona para mí, lo bueno es que puedo entenderlo bastante pasado, tan simple. –

44

Puede DEJAR UNIR las dos tablas. Si no hay una fila correspondiente en la segunda tabla, los valores serán NULL.

SELECT id FROM partmaster LEFT JOIN product_details ON (...) WHERE product_details.part_num IS NULL 
+4

Esto realmente debería ser la respuesta aceptada. No veo el sentido de una sub-selección en este caso:/ –

+2

La subselección es más fácil de entender para los novatos. – Johan

3

Así que hay un montón de publicaciones en la web que muestran cómo hacer esto, he encontrado 3 formas, lo mismo que señaló Johan & Sjoerd. No pude hacer que ninguna de estas consultas funcionara, bueno, obviamente funcionan bien, es mi base de datos que no funciona correctamente y todas esas consultas corrieron lentamente.

así que trabajé por otro camino que otra persona puede encontrar útil:

El jist básica de la misma es crear una tabla temporal y llenarlo con toda la información, a continuación, quitar todas las filas que están en la otra mesa.

Así que hice estas 3 consultas, y se ejecutó rápidamente (en un par de momentos).

CREATE TEMPORARY TABLE 

`database1`.`newRows` 

SELECT 

`t1`.`id` AS `columnID` 

FROM 

`database2`.`table` AS `t1` 

.

CREATE INDEX `columnID` ON `database1`.`newRows`(`columnID`) 

.

DELETE FROM `database1`.`newRows` 

WHERE 

EXISTS(
    SELECT `columnID` FROM `database1`.`product_details` WHERE `columnID`=`database1`.`newRows`.`columnID` 
) 
+0

Corre rápido porque solo está comparando el primer producto, o no estoy viendo esto bien ?! – MPaulo

2

Para ampliar la respuesta de Johan, si la columna part_num en la selección secundaria puede contener valores nulos, la consulta se romperá.

Para corregir este problema, agregue un cheque nulo ...

SELECT pm.id FROM r2r.partmaster pm 
WHERE pm.id NOT IN 
     (SELECT pd.part_num FROM wpsapi4.product_details pd 
        and pd.part_num is not null) 
  • Lo sentimos pero no pude añadir un comentario como yo no tengo el representante!
+1

'no en' seguro puede ser desagradable – Drew

Cuestiones relacionadas