Aujourd'hui, j'ai essayé des requêtes MySQL plus complexes et j'ai remarqué que LEFT JOIN de MySQL ne fonctionnait pas avec la clause WHERE. Je veux dire, il renvoie certains enregistrements, mais pas ceux qui sont vides du côté droit.
Par exemple, disons que nous avons des tables:
des albums; albums_rap id pistes du titre de l'artiste; id artiste titre rang ---- -------- ---------- ---------------; ---- --------- ----- -------------- 1 John Doe Mix CD 20; 3 Marque CD n ° 7 15 2 Marque CD n ° 7 35;
Et quand j'exécute cette requête:
SELECT
t1.artist as artist,
t1.title as title,
t1.tracks as tracks,
t2.rank as rank,
FROM
albums as t1
LEFT JOIN
albums_rap as t2
ON
t1.artist LIKE t2.artist
AND
t1.title LIKE t2.title
WHERE
t2.rank != 17
J'ai compris:
titre d'artiste titre rang ------ ----- ------ ----- Marque CD n ° 7 35 15
mais quand je remplace "WHERE" par "AND" dans cette requête, je reçois:
titre d'artiste titre rang ------ --------- ------ ----- Marque CD n ° 7 35 15 John Doe Mix CD 20 NULL
Pourquoi le premier ne renvoie pas d'enregistrements avec "NULL" (null n'est pas égal à 17 ...)
J'espère que vous avez compris ce que je voulais dire et vous m'expliquerez d'une manière ou d'une autre la différence. Désolé pour mon mauvais anglais, ce n'est pas ma langue maternelle.
Une condition de jointure gauche et un filtre de condition ne sont pas identiques. Les données sont filtrées par la clause where après la jointure physique. Si vous regardez une jointure gauche, toutes les lignes de votre table gauche seront renvoyées. Une fois que vous avez une clause where, le résultat de la jointure est filtré. Le résultat est donc similaire à une jointure interne. Vous voudrez vous concentrer sur les deux diagrammes du côté gauche de l'image ci-dessous.
Premier cas:
Une fois joints, les enregistrements sont filtrés par la (clause WHERE). Donc, seulement 1 résultat.
Deuxième cas (lorsque vous remplacez WHERE par AND)
Renverra toutes les entrées de jointure + entrées satisfaites dans la deuxième condition (t2.rank! = 17). C’est pourquoi ici vous obtenez 2 enregistrements (un de jointure + un autre de clause AND)
"Le mot clé LEFT JOIN renvoie toutes les lignes de la table de gauche (table1), avec les lignes correspondantes dans la table de droite (table2). Le résultat est NULL du côté droit en l'absence de correspondance ."
La citation ci-dessus est de w3schools.com
Cependant, lorsque vous placez une clause WHERE sur un LEFT JOIN, SQL le traite maintenant comme un INNER JOIN et:
"Le mot clé INNER JOIN sélectionne toutes les lignes des deux tables tant qu'il existe une correspondance entre les colonnes des deux tables."
Également cité de w3schools.com
TLDR;
L'introduction de la clause WHERE dans un LEFT OUTER JOIN confère à la jointure le comportement d'un INNER JOIN
La solution à cette question devient assez intuitive une fois que l’on connaît l’ordre d’exécution ou les phases de traitement de requêtes logiques de l’instruction SQL. La commande est: -
1. FROM
2. ON
3. OUTER
4. WHERE
5. GROUP BY
6. CUBE | ROLLUP
7. HAVING
8. SELECT
9. DISTINCT
10. ORDER BY
11. TOP
Comme ON est exécuté avant la partie OUTER (LEFT/RIGHT) (ajout de lignes de valeur NULL) de JOIN, le 1er cas contient des lignes avec des valeurs NULL dans la colonne de rang. Dans le 2e cas, les lignes sont filtrées en fonction sur les valeurs de la colonne de rang après l'exécution de OUTER JOIN (LEFT JOIN ici). Par conséquent, les lignes avec des valeurs NULL dans la colonne de classement sont filtrées.
Une chose très importante que vous pouvez remarquer dans votre requête SQL est la comparaison avec NULL Cette zone nécessite une attention particulière, car les valeurs NULL sont associées aux valeurs NULL/NON NULL à l'aide des opérateurs arithmétiques normaux. result NULL (ni les valeurs TRUE ni FALSE), car NULL signifie qu'aucune valeur n'est disponible pour la comparaison. Ce comportement est défini dans la norme ANSI SQL 92. (Ceci peut être annulé en désactivant le paramètre ansi null (le nom réel peut varier) dans certains processeurs SQL) Ainsi, votre requête SQL with clause clause filtre les lignes avec la valeur NULL dans la colonne rank qui peut sembler contre-intuitive en raison de "17! = NULL" semble TRUE ex-
NULL = NULL résultats NULL/UNKNOWN
17 = résultats NULL NULL/UNKNOWN
17! = NULL résultats NULL? INCONNU
Voici quelques articles/blogs intéressants à titre de référence:
http://blog.sqlauthority.com/2009/04/06/sql-server-logical-query-processing-phases-order-of-statement-execution/http://blog.sqlauthority.com/2009/03/15/sql-server-interesting-observation-of-on-clause-on-left-join-how-on-clause-effects-resultset-in-left-join/http://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-any-chose-in-sql/