J’ai les deux tables SQL suivantes (en 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é effectués par des personnes dont le phone_number
ne figure 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 y a plusieurs façons de procéder, avec une efficacité variable, en fonction de la qualité de votre optimiseur de requête et de la taille relative de vos deux tables:
Ceci est la déclaration la plus courte et peut être plus rapide si votre annuaire 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 au 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 cela, comme d’autres l’ont dit, il est normalement préférable de ne sélectionner que les colonnes que vous voulez, pas « *
»)
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, permettant à l’optimiseur de requêtes de travailler sa magie.
De même, évitez “SELECT *” car il peut casser votre code si quelqu’un modifie les tables ou les vues sous-jacentes (et il est inefficace).
Le code ci-dessous serait un peu plus efficace que les réponses présentées ci-dessus pour traiter des ensembles de données plus importants.
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 retournera 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