MySQL sélectionnez les lignes où LEFT join est null
J'ai ces tables MySQL:
Tableau1:
id | writer
1 | Bob
2 | Marley
3 | Michael
Tableau2:
user_one | user_two
1 | 2
Et cette requête:
SELECT table1.id FROM table1 LEFT JOIN table2 ON table1.id = table2.user_one
Cette requête renverra toutes les lignes de table1 qui sont 1,2,3
Je veux sélectionner uniquement les lignes qui ne se trouvent pas dans l'articulation de gauche. Donc, il ne devrait retourner que la ligne avec id 3
Je veux en quelque sorte le contraire de INNER JOIN qui ne sélectionnera que les lignes qui se trouvent dans la jointure. Comment obtenir le contraire comme si LEFT join existe, l'ignorer et passer à la ligne suivante. J'espère que je suis clair
6 réponses
Vous pouvez utiliser la requête suivante:
SELECT table1.id
FROM table1
LEFT JOIN table2
ON table1.id IN (table2.user_one, table2.user_two)
WHERE table2.user_one IS NULL;
Bien que, en fonction de vos index sur table2
Vous pouvez constater que deux jointures fonctionnent mieux:
SELECT table1.id
FROM table1
LEFT JOIN table2 AS t1
ON table1.id = t1.user_one
LEFT JOIN table2 AS t2
ON table1.id = t2.user_two
WHERE t1.user_one IS NULL
AND t2.user_two IS NULL;
L'une des meilleures approches si vous ne voulez pas renvoyer de colonnes à partir de table2
est d'utiliser le NOT EXISTS
SELECT table1.id
FROM table1 T1
WHERE
NOT EXISTS (SELECT *
FROM table2 T2
WHERE T1.id = T2.user_one
OR T1.id = T2.user_two)
Sémantiquement, cela dit ce que vous voulez interroger: Sélectionnez chaque ligne où il n'y a pas d'enregistrement correspondant dans la deuxième table.
MySQL est optimisé pour EXISTS
: Elle retourne dès qu'il trouve le premier enregistrement correspondant.
Voici une requête qui retourne uniquement les lignes où aucune correspondance n'a été trouvée dans les deux colonnes user_one
et user_two
de table2
:
SELECT T1.*
FROM table1 T1
LEFT OUTER JOIN table2 T2A ON T2A.user_one = T1.id
LEFT OUTER JOIN table2 T2B ON T2B.user_two = T1.id
WHERE T2A.user_one IS NULL
AND T2B.user_two IS NULL
Il y a une jointure pour chaque colonne (user_one
et user_two
) et la requête ne renvoie que les lignes qui n'ont pas de jointure correspondante.
J'espère que cela vous aidera.
Essayez:
SELECT A.id FROM
(
SELECT table1.id FROM table1
LEFT JOIN table2 ON table1.id = table2.user_one
WHERE table2.user_one IS NULL
) A
JOIN (
SELECT table1.id FROM table1
LEFT JOIN table2 ON table1.id = table2.user_two
WHERE table2.user_two IS NULL
) B
ON A.id = B.id
Voir Démo
, Ou vous pouvez utiliser deux LEFT JOINS
avec des alias comme:
SELECT table1.id FROM table1
LEFT JOIN table2 A ON table1.id = A.user_one
LEFT JOIN table2 B ON table1.id = B.user_two
WHERE A.user_one IS NULL
AND B.user_two IS NULL
Voir 2ème Démo
Essayez la requête suivante: -
SELECT table1.id
FROM table1
where table1.id
NOT IN (SELECT user_one
FROM Table2
UNION
SELECT user_two
FROM Table2)
J'espère que cela vous aidera.
SELECT table1.id
FROM table1
LEFT JOIN table2 ON table1.id = table2.user_one
WHERE table2.user_one is NULL