2010-12-06 4 views
1

J'ai eu deux comme une clé étrangère tables MySql de CARS et DRIVERS avec l'attribut licenseNumber
.requête MySql pour trouver les enregistrements ne sont pas présents dans une autre table

Quelle serait la requête pour trouver les noms des conducteurs qui n'avaient pas de voiture?

Je pensais:

SELECT DISTINCT D.name 
FROM drivers D, cars C 
WHERE 
D.licenseNumber = C.licenseNumber AND 
    D.licenseNumber NOT IN (SELECT licenseNumber FROM cars) 

Mais cela ne retourne rien.
J'ai l'impression de trop réfléchir un peu.
Une aide?

+0

Vous allez vous donner un coup de pied quand vous réaliserez ce que vous avez mal fait. :-) –

+0

Le numéro de liceense est la clé primaire pour CARS et la clé étrangère pour DRIVERS? Alors votre question n'est pas possible. Si aucune voiture ne signifie aucune clé primaire pour les voitures, aucune clé étrangère possible. – Tauquir

Répondre

3
SELECT D.name 
FROM drivers D 
WHERE NOT EXISTS(SELECT * FROM cars c 
       WHERE D.licenseNumber = C.licenseNumber) 
+0

Merci, cela fonctionne et semble être la solution la plus évidente. Je ne peux pas croire que je n'y ai pas pensé! – bananamana

+0

Cette requête doit faire une sous-requête séparée pour chaque 'Pilote'. Je sais que MySQL peut faire de puissantes optimisations mais je ne pense pas qu'elles s'étendent aussi loin. Mis à part les inconvénients de la performance, je pense aussi que cette solution est trop exotique pour un «problème» SQL aussi commun. – Jochem

+0

PS: Si vous n'aimez vraiment pas les jointures, et que vous voulez résoudre ce problème avec des sous-requêtes, regardez la solution de Don Grossman. – Jochem

2

Aucune ligne ne peut correspondre à cette requête (si licenseNumber n'était pas dans la table cars, comment cars.licenseNumber = drivers.licenseNumber?).

SELECT DISTINCT name FROM drivers WHERE licenseNumber NOT IN (SELECT licenseNumber FROM cars) 
2

Utilisez LEFT JOIN:

SELECT DISTINCT D.name 
    FROM drivers D 
    LEFT JOIN cars C ON D.licenseNumber = C.licenseNumber 
    WHERE C.SOMECOLUMNTHATCANNOTBENULL IS NULL 

Bien que vous pourriez faire

SELECT DISTINCT D.name FROM drivers D WHERE D.licenseNumber is NULL 

Mais cela dépend entièrement de la façon dont vous avez structuré vos données!

[EDIT: LEFT JOIN fonctionne comme ceci: il prend TOUTES les lignes de la colonne de gauche mentionnée - les pilotes dans ce cas - et pour chaque essaie de faire correspondre une voiture (en utilisant la condition après ON). Si aucune voiture n'est trouvée, une ligne pour ce pilote est quand même retournée, les colonnes qui devraient normalement provenir de la voiture sont définies sur NULL. (Si plusieurs voitures se trouvent pour un seul pilote, plusieurs lignes sont renvoyées).]

0

SELECT DISTINCT D.name, c.id
FROM drivers D LEFT JOIN cars C
ON D.licenseNumber = C.licenseNumber WHERE c.id IS NULL
J'ai ajouté l'identifiant de voiture, donc je peux trouver pilote ne dispose pas d'une voiture (c.id est null)

Questions connexes