web-dev-qa-db-fra.com

MySQL sélectionne des lignes qui n'ont pas de colonne correspondante dans une autre table

Je n'arrive pas à comprendre cela jusqu'à présent. J'essaie de joindre deux tables et de sélectionner uniquement les lignes de la table A qui n'ont pas de colonne correspondante dans la table B. Par exemple, supposons que nous avons une table d'utilisateurs et une table envoyée.

users table a les colonnes suivantes: id, username
sent table a les colonnes suivantes: id, username

Je veux sélectionner toutes les lignes de usersusername n'existe pas dans la table sent. Donc, si tom est dans users et dans sent, il ne sera pas sélectionné. S'il est dans users mais pas dans sent, il sera sélectionné. J'ai essayé mais cela n'a pas fonctionné du tout:

SELECT pooltest.name,senttest.sentname 
FROM pooltest,senttest 
WHERE pooltest.name != senttest.sentname
30
xendi

Essayez ce SQL:

SELECT users.username
FROM  users
LEFT JOIN sent ON sent.username = users.username
WHERE sent.username IS NULL;

La meilleure façon à mon avis serait:

SELECT users.username
FROM  users
LEFT JOIN sent ON sent.id = users.id
WHERE sent.id IS NULL;

Comme les deux champs id, seraient indexés (clé primaire j'aurais pensé) donc cette requête serait mieux optimisée que la première que j'ai suggérée.

Cependant, vous pouvez trouver ma première suggestion meilleure pour vous, cela dépend de vos besoins pour votre application.

18
Haroon

En règle générale, vous utiliseriez NOT EXISTS pour ce type de requête

SELECT p.Name
FROM   pooltest p
WHERE  NOT EXISTS (SELECT s.Name
                   FROM   senttest s
                   WHERE  s.Name = p.Name)

Une alternative serait d'utiliser un LEFT OUTER JOIN et recherchez NULL

SELECT p.Name
FROM   pooltest p
       LEFT OUTER JOIN senttest s ON s.Name = p.Name
WHERE  s.Name IS NULL

Notez que la syntaxe de jointure implicite que vous utilisez est considérée comme obsolète et doit être remplacée par une jointure explicite.

59