Maison >base de données >tutoriel mysql >Pourquoi une LEFT JOIN devient-elle une INNER JOIN lors du filtrage sur une colonne de droite dans la clause WHERE ?

Pourquoi une LEFT JOIN devient-elle une INNER JOIN lors du filtrage sur une colonne de droite dans la clause WHERE ?

DDD
DDDoriginal
2024-12-29 14:47:11745parcourir

Why Does a LEFT JOIN Become an INNER JOIN When Filtering on a Right-Side Column in the WHERE Clause?

Question de comportement de jointure gauche : transformation en jointure interne avec la clause WHERE

Considérez l'instruction SQL suivante :

SELECT
    a.foo
    b.bar
    c.foobar
FROM tableOne AS a
INNER JOIN tableTwo AS b ON a.pk = b.fk
LEFT JOIN tableThree AS c ON b.pk = c.fk
WHERE a.foo = 'something'
AND c.foobar = 'somethingelse'

Dans ce scénario, on s'attend à un comportement de jointure à gauche. Cependant, le comportement observé est que la jointure gauche semble se transformer en une jointure interne basée sur la présence de la clause AND c.foobar = 'somethingelse'. Les lignes dépourvues d'une valeur 'quelque chose d'autre' correspondante dans la table Trois ne sont pas renvoyées.

Comprendre le comportement

Le 關鍵點 réside dans l'interaction entre la clause WHERE et LEFT JOIN . Lorsqu'une valeur non NULL est spécifiée à partir du côté droit d'une jointure gauche dans une clause WHERE, les valeurs NULL sont éliminées, transformant ainsi la jointure en une jointure interne.

Dans ce cas, le AND c. La clause foobar = 'somethingelse' filtre les lignes de la tableThree où foobar est NULL. Cela signifie que seules les lignes avec des valeurs non NULL correspondantes dans tableTwo et tableThree sont renvoyées.

Solutions

Pour résoudre ce problème et restaurer la jointure gauche prévue, il y a sont deux options :

  1. Modifier OÙ Clause :
AND (c.foobar = 'somethingelse' OR c.foobar IS NULL)

Cet ajout permet d'inclure les valeurs NULL de la tableThree, préservant ainsi le comportement de jointure gauche.

  1. Déplacer vers le prédicat de jointure :
LEFT JOIN tableThree AS c ON b.pk = c.fk
AND c.foobar = 'somethingelse'

En déplaçant la condition c.foobar dans la jointure prédicat, la requête spécifie explicitement les critères de filtrage souhaités dans la jointure, garantissant que seules les lignes correspondantes sont jointes.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn