146 votos

SQL - buscar registros de una tabla que ' existe en otro

Tengo las siguientes dos tablas SQL (MySQL):

Phone_book
+----+------+--------------+
| id | name | phone_number |
+----+------+--------------+
| 1  | John | 111111111111 |
+----+------+--------------+
| 2  | Jane | 222222222222 |
+----+------+--------------+

Call
+----+------+--------------+
| id | date | phone_number |
+----+------+--------------+
| 1  | 0945 | 111111111111 |
+----+------+--------------+
| 2  | 0950 | 222222222222 |
+----+------+--------------+
| 3  | 1045 | 333333333333 |
+----+------+--------------+

¿Cómo puedo saber que las llamadas fueron hechas por personas cuya phone_number no está en el Phone_book ? Sería la salida deseada:

Call
+----+------+--------------+
| id | date | phone_number |
+----+------+--------------+
| 3  | 1045 | 333333333333 |
+----+------+--------------+

Cualquier ayuda sería mucho apreció.

198voto

Alnitak Puntos 143355

Hay varias formas de hacer esto, variando la eficiencia, dependiendo de cómo de buena es tu consulta optimizador de conversiones es, y el tamaño relativo de las dos tablas:

Este es el más corto de instrucción, y puede ser más rápida si su agenda es muy corto:

SELECT  *
FROM    Call
WHERE   phone_number NOT IN (SELECT phone_number FROM Phone_book)

alternativamente, (gracias a Alterlife)

SELECT *
FROM   Call
WHERE  NOT EXISTS
  (SELECT *
   FROM   Phone_book
   WHERE  Phone_book.phone_number = Call.phone_number)

o (gracias a Kieran)

SELECT * 
FROM   Call
LEFT OUTER JOIN Phone_Book
  ON (Call.phone_number = Phone_book.phone_number)
  WHERE Phone_book.phone_number IS NULL

(ignorando que, como otros han dicho, normalmente es mejor seleccionar las columnas que desea, no '*')

40voto

WOPR Puntos 2374
SELECT Call.ID, Call.date, Call.phone_number 
FROM Call 
LEFT OUTER JOIN Phone_Book 
  ON (Call.phone_number=Phone_book.phone_number) 
  WHERE Phone_book.phone_number IS NULL

Debe eliminar la subconsulta, permitiendo que el optimizador de consultas a solucionarlo es mágico.

También, evite "SELECT *" porque puede romper su código si alguien altera las tablas o vistas subyacentes (y es ineficiente).

12voto

Alterlife Puntos 2914

El código siguiente sería un poco más eficiente que las respuestas presentadas arriba cuando se trata con grandes conjuntos de datos.

SELECT * FROM Call WHERE 
NOT EXISTS (SELECT 'x' FROM Phone_book where 
Phone_book.phone_number = Call.phone_number)

3voto

Nat Geo Puntos 86

Creo

SELECT CALL.* FROM CALL LEFT JOIN Phone_book ON 
CALL.id = Phone_book.id WHERE Phone_book.name IS NULL

2voto

Vlado Puntos 136
SELECT DISTINCT Call.id 
FROM Call 
LEFT OUTER JOIN Phone_book USING (id) 
WHERE Phone_book.id IS NULL

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X