Après l'avoir lu, il ne s'agit pas d' un doublon de jointures SQL explicites et implicites . La réponse peut être liée (ou même la même) mais la question est différente.
Quelle est la différence et que devrait-il y avoir dans chacun?
Si je comprends bien la théorie, l'optimiseur de requêtes devrait pouvoir utiliser les deux de manière interchangeable.
Réponses:
Ce n'est pas la même chose.
Considérez ces requêtes:
et
Le premier retournera une commande et ses lignes, le cas échéant, pour le numéro de commande
12345
. Le second retournera toutes les commandes, mais seulement la commande12345
aura des lignes associées.Avec un
INNER JOIN
, les clauses sont effectivement équivalentes. Cependant, ce n'est pas parce qu'ils sont fonctionnellement les mêmes, en ce qu'ils produisent les mêmes résultats, que les deux types de clauses ont la même signification sémantique.la source
Questions pour les jointures externes
une.
WHERE
clause: Après adhésion. Les enregistrements seront filtrés une fois la jointure effectuée.b.
ON
clause - Avant d' adhérer. Les enregistrements (du tableau de droite) seront filtrés avant de rejoindre. Cela peut finir comme nul dans le résultat (depuis la jointure EXTERNE).Exemple : considérez les tableaux ci-dessous:
a)
WHERE
Clause intérieure :b)
JOIN
Clause intérieurela source
intermediate join table
? Une commande «Expliquer»?Sur
INNER JOIN
s ils sont interchangeables, et l'optimiseur les réorganisera à volonté.Sur
OUTER JOIN
s, ils ne sont pas nécessairement interchangeables, selon le côté de la jointure dont ils dépendent.Je les mets aux deux endroits en fonction de la lisibilité.
la source
Orders.Join( OrderLines, x => x.ID, x => OrderID, (o,l) => new {Orders = o, Lines = l}).Where( ol => ol.Orders.ID = 12345)
Ma façon de procéder est:
Mettez toujours les conditions de jointure dans la
ON
clause si vous faites unINNER JOIN
. Donc, n'ajoutez aucune condition WHERE à la clause ON, mettez-les dans laWHERE
clause.Si vous effectuez une
LEFT JOIN
, ajoutez des conditions WHERE à laON
clause de la table dans le côté droit de la jointure. C'est un must, car l'ajout d'une clause WHERE qui fait référence au côté droit de la jointure convertira la jointure en INNER JOIN.L'exception est lorsque vous recherchez les enregistrements qui ne se trouvent pas dans une table particulière. Vous ajoutez la référence à un identifiant unique (ce n'est pas toujours NULL) dans la droite table de jointure à la clause WHERE de cette façon:
WHERE t2.idfield IS NULL
. Ainsi, la seule fois où vous devez référencer une table sur le côté droit de la jointure est de rechercher les enregistrements qui ne figurent pas dans la table.la source
Sur une jointure intérieure, ils signifient la même chose. Cependant, vous obtiendrez des résultats différents dans une jointure externe selon que vous placez la condition de jointure dans la clause WHERE vs ON. Jetez un oeil à cette question connexe et cette réponse (par moi).
Je pense que cela a le plus de sens d'avoir l'habitude de toujours mettre la condition de jointure dans la clause ON (à moins qu'il ne s'agisse d'une jointure externe et que vous ne la vouliez réellement dans la clause where) car cela le rend plus clair pour quiconque lit votre requête les conditions dans lesquelles les tables sont jointes, et cela permet également d'éviter que la clause WHERE ne soit longue de plusieurs dizaines de lignes.
la source
Relation de table
Considérant que nous avons les tableaux
post
etpost_comment
tableaux suivants:Le
post
a les enregistrements suivants:et
post_comment
a les trois lignes suivantes:SQL INNER JOIN
La clause SQL JOIN vous permet d'associer des lignes appartenant à différentes tables. Par exemple, un CROSS JOIN créera un produit cartésien contenant toutes les combinaisons possibles de lignes entre les deux tables de jonction.
Bien que CROSS JOIN soit utile dans certains scénarios, la plupart du temps, vous souhaitez joindre des tables en fonction d'une condition spécifique. Et c'est là que INNER JOIN entre en jeu.
Le SQL INNER JOIN nous permet de filtrer le produit cartésien de joindre deux tables en fonction d'une condition qui est spécifiée via la clause ON.
SQL INNER JOIN - ON condition "toujours vrai"
Si vous fournissez une condition "toujours vrai", l'INNER JOIN ne filtrera pas les enregistrements joints et le jeu de résultats contiendra le produit cartésien des deux tables de jointure.
Par exemple, si nous exécutons la requête SQL INNER JOIN suivante:
Nous obtiendrons toutes les combinaisons
post
etpost_comment
enregistrements:Donc, si la condition de la clause ON est "toujours vraie", l'INNER JOIN est simplement équivalent à une requête CROSS JOIN:
SQL INNER JOIN - ON "toujours faux" condition
D'un autre côté, si la condition de la clause ON est "toujours fausse", alors tous les enregistrements joints vont être filtrés et le jeu de résultats sera vide.
Donc, si nous exécutons la requête SQL INNER JOIN suivante:
Nous n'obtiendrons aucun résultat:
En effet, la requête ci-dessus est équivalente à la requête CROSS JOIN suivante:
Clause SQL INNER JOIN - ON utilisant les colonnes Clé étrangère et Clé primaire
La condition de clause ON la plus courante est celle qui fait correspondre la colonne Clé étrangère de la table enfant à la colonne Clé primaire de la table parent, comme illustré par la requête suivante:
Lors de l'exécution de la requête SQL INNER JOIN ci-dessus, nous obtenons le jeu de résultats suivant:
Ainsi, seuls les enregistrements qui correspondent à la condition de la clause ON sont inclus dans le jeu de résultats de la requête. Dans notre cas, le jeu de résultats contient tout le
post
long avec leurspost_comment
enregistrements. Lespost
lignes qui n'ont aucun associépost_comment
sont exclues car elles ne peuvent pas satisfaire à la condition de clause ON.Encore une fois, la requête SQL INNER JOIN ci-dessus est équivalente à la requête CROSS JOIN suivante:
Les lignes non frappées sont celles qui satisfont la clause WHERE, et seuls ces enregistrements vont être inclus dans le jeu de résultats. C'est le meilleur moyen de visualiser le fonctionnement de la clause INNER JOIN.
Conclusion
Une instruction INNER JOIN peut être réécrite en tant que CROSS JOIN avec une clause WHERE correspondant à la même condition que vous avez utilisée dans la clause ON de la requête INNER JOIN.
la source
Il y a une grande différence entre la clause where par rapport à l' article , quand il vient à se joindre à gauche.
Voici un exemple:
Il y a id de la table t2.
Requête sur "on clause":
Requête sur "clause where":
Il est clair que la première requête renvoie un enregistrement de t1 et sa ligne dépendante de t2, le cas échéant, pour la ligne t1.v = 'K'.
La deuxième requête renvoie des lignes de t1, mais uniquement pour t1.v = 'K' aura une ligne associée.
la source
En termes d'optimiseur, cela ne devrait pas faire de différence si vous définissez vos clauses de jointure avec ON ou WHERE.
Cependant, à mon humble avis, je pense qu'il est beaucoup plus clair d'utiliser la clause ON lors de l'exécution de jointures. De cette façon, vous avez une section spécifique de votre requête qui dicte la façon dont la jointure est gérée par rapport au mélange des autres clauses WHERE.
la source
Prenons ces tableaux:
UNE
B
id_A
être une clé étrangère à la tableA
Écriture de cette requête:
Fournira ce résultat:
Ce qui est en A mais pas en B signifie qu'il y a des valeurs nulles pour B.
Maintenant, considérons une partie spécifique de
B.id_A
, et mettons-la en évidence à partir du résultat précédent:Écriture de cette requête:
Fournira ce résultat:
Parce que cela supprime dans la jointure interne les valeurs qui ne sont pas dans
B.id_A = SpecificPart
Maintenant, changeons la requête en ceci:
Le résultat est maintenant:
Parce que tout le résultat est filtré contre la
B.id_A = SpecificPart
suppression des partiesB.id_A = NULL
, qui sont dans le A qui ne sont pas dans le Bla source
Essayez-vous de joindre des données ou de filtrer des données?
Pour plus de lisibilité, il est plus judicieux d'isoler ces cas d'utilisation respectivement sur ON et WHERE.
Il peut devenir très difficile de lire une requête dans laquelle la condition JOIN et une condition de filtrage existent dans la clause WHERE.
En termes de performances, vous ne devriez pas voir de différence, bien que différents types de SQL gèrent parfois la planification des requêtes différemment, il peut donc être utile d'essayer
¯\_(ツ)_/¯
(soyez conscient que la mise en cache affecte la vitesse de requête)Comme d'autres l'ont également remarqué, si vous utilisez une jointure externe, vous obtiendrez des résultats différents si vous placez la condition de filtre dans la clause ON car elle n'affecte qu'une des tables.
J'ai écrit un article plus détaillé à ce sujet ici: https://dataschool.com/learn/difference-between-where-and-on-in-sql
la source
En SQL, les clauses 'WHERE' et 'ON' sont des sortes de statemants conditionnels, mais la principale différence entre elles est que la clause 'Where' est utilisée dans les instructions Select / Update pour spécifier les conditions, tandis que la clause 'ON' est utilisé dans les jointures, où il vérifie ou vérifie si les enregistrements sont mis en correspondance dans les tables cible et source, avant que les tables ne soient jointes
Par exemple: - 'OERE'
Par exemple: - 'ON'
Il y a deux tables employee et employee_details, les colonnes correspondantes sont employee_id.
J'espère avoir répondu à votre question. Revenez pour toute clarification.
la source
WHERE
à la place deON
, n'est-ce pas? sqlfiddle.com/#!2/ae5b0/14/0Je pense que c'est l'effet de séquence de jointure. Dans le cas de jointure supérieur gauche, SQL fait d'abord la jointure gauche, puis fait où le filtre. Dans le cas inférieur, recherchez d'abord Orders.ID = 12345, puis joignez-vous.
la source
Pour une jointure intérieure,
WHERE
etON
peut être utilisé de manière interchangeable. En fait, il est possible de l'utiliserON
dans une sous-requête corrélée. Par exemple:C'est (à mon humble avis) complètement déroutant pour un humain, et il est très facile d'oublier de lier
table1
à quoi que ce soit (car la table "driver" n'a pas de clause "on"), mais c'est légal.la source
pour de meilleures performances, les tables doivent avoir une colonne indexée spéciale à utiliser pour JOINS.
donc si la colonne sur laquelle vous conditionnez ne fait pas partie de ces colonnes indexées, je soupçonne qu'il vaut mieux la conserver dans WHERE.
vous vous JOIGNEZ donc en utilisant les colonnes indexées, puis après JOIN vous exécutez la condition sur la colonne non indexée.
la source
Normalement, le filtrage est traité dans la clause WHERE une fois que les deux tables ont déjà été jointes. Il est possible, cependant, que vous souhaitiez filtrer une ou les deux tables avant de les rejoindre. c'est-à-dire que la clause where s'applique à l'ensemble des résultats alors que la clause on ne s'applique qu'à la jointure en question.
la source
Je pense que cette distinction peut être mieux expliquée via l' ordre logique des opérations dans SQL , qui est simplifié:
FROM
(y compris les jointures)WHERE
GROUP BY
HAVING
WINDOW
SELECT
DISTINCT
UNION
,INTERSECT
,EXCEPT
ORDER BY
OFFSET
FETCH
Les jointures ne sont pas une clause de l'instruction select, mais un opérateur à l'intérieur de
FROM
. Ainsi, toutes lesON
clauses appartenant à l'JOIN
opérateur correspondant se sont "déjà produites" logiquement au moment où le traitement logique atteint laWHERE
clause. Cela signifie que dans le cas d'unLEFT JOIN
, par exemple, la sémantique de la jointure externe s'est déjà produite au moment où leWHERE
clause est appliquée.J'ai expliqué l'exemple suivant plus en détail dans cet article de blog . Lors de l'exécution de cette requête:
Cela
LEFT JOIN
n'a pas vraiment d'effet utile, car même si un acteur n'a pas joué dans un film, l'acteur sera filtré comme il leFILM_ID
seraNULL
et laWHERE
clause filtrera une telle ligne. Le résultat est quelque chose comme:C'est-à-dire comme si nous rejoignions intérieurement les deux tables. Si nous déplaçons le prédicat de filtre dans la
ON
clause, il devient maintenant un critère pour la jointure externe:Cela signifie que le résultat contiendra des acteurs sans aucun film, ou sans aucun film avec
FILM_ID < 10
En bref
Mettez toujours votre prédicat là où il est le plus logique, logiquement.
la source
Concernant votre question,
Il en est de même à la fois sur ou sur une jointure interne tant que votre serveur peut l'obtenir:
et
L'option «où» que tous les interprètes ne connaissent pas doit donc être évitée. Et bien sûr, la clause «on» est plus claire.
la source
c'est ma solution.
Vous devez avoir le
GROUP BY
pour le faire fonctionner.J'espère que cette aide.
la source