J'ai les deux tables SQL suivantes (dans 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 |
+----+------+--------------+
Comment savoir quels appels ont été passés par des personnes dont phone_number
n'est pas dans le Phone_book
? La sortie souhaitée serait:
Call
+----+------+--------------+
| id | date | phone_number |
+----+------+--------------+
| 3 | 1045 | 333333333333 |
+----+------+--------------+
Toute aide serait très appréciée.
Il existe différentes façons de procéder, avec une efficacité variable, en fonction de la qualité de votre optimiseur de requêtes et de la taille relative de vos deux tables:
C'est la déclaration la plus courte, et peut être la plus rapide si votre répertoire est très court:
SELECT *
FROM Call
WHERE phone_number NOT IN (SELECT phone_number FROM Phone_book)
alternativement (grâce à Alterlife )
SELECT *
FROM Call
WHERE NOT EXISTS
(SELECT *
FROM Phone_book
WHERE Phone_book.phone_number = Call.phone_number)
ou (grâce à WOPR)
SELECT *
FROM Call
LEFT OUTER JOIN Phone_Book
ON (Call.phone_number = Phone_book.phone_number)
WHERE Phone_book.phone_number IS NULL
(en ignorant que, comme d'autres l'ont déjà dit, il est généralement préférable de sélectionner uniquement les colonnes souhaitées, et non '*
')
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
Devrait supprimer la sous-requête, ce qui permettrait à l’optimiseur de requêtes d’exploiter sa magie.
Aussi, évitez "SELECT *" car cela peut casser votre code si quelqu'un altère les tables ou les vues sous-jacentes (et que cela est inefficace).
Le code ci-dessous serait un peu plus efficace que les réponses présentées ci-dessus lorsqu'il s'agit de jeux de données plus volumineux.
SELECT * FROM Call WHERE
NOT EXISTS (SELECT 'x' FROM Phone_book where
Phone_book.phone_number = Call.phone_number)
SELECT DISTINCT Call.id
FROM Call
LEFT OUTER JOIN Phone_book USING (id)
WHERE Phone_book.id IS NULL
Cela renverra les identifiants supplémentaires manquants dans votre table Phone_book.
Je pense
SELECT CALL.* FROM CALL LEFT JOIN Phone_book ON
CALL.id = Phone_book.id WHERE Phone_book.name IS NULL
SELECT t1.ColumnID,
CASE
WHEN NOT EXISTS( SELECT t2.FieldText
FROM Table t2
WHERE t2.ColumnID = t1.ColumnID)
THEN t1.FieldText
ELSE t2.FieldText
END FieldText
FROM Table1 t1, Table2 t2
SELECT name, phone_number FROM Call a
WHERE a.phone_number NOT IN (SELECT b.phone_number FROM Phone_book b)
Alternativement
select id from call
minus
select id from phone_number