JOINTURE INTERNE SUR vs clause where
Pour des raisons de simplicité, supposons que tous les champs sont NOT NULL
.
Que vous pouvez faire:
SELECT
table1.this, table2.that, table2.somethingelse
FROM
table1, table2
WHERE
table1.foreignkey = table2.primarykey
AND (some other conditions)
Ou encore:
SELECT
table1.this, table2.that, table2.somethingelse
FROM
table1 INNER JOIN table2
ON table1.foreignkey = table2.primarykey
WHERE
(some other conditions)
Ces deux fonctionnent sur le même chemin, en MySQL
?
- c'est ici
- double possible de SQL left join vs plusieurs tables à PARTIR de la ligne?
- Si j'ai bien compris, la première variante est la norme ANSI SQL-89 implicite de la syntaxe et de la deuxième variante est la norme ANSI SQL-92 explicite de la syntaxe de jointure. Les deux aboutissent au même résultat en se conformant SQL de mise en œuvre et à la fois résultat sera le même plan de requête dans bien fait implémentations de SQL. Personnellement, je préfère SQL-89 syntaxe mais beaucoup de gens préfèrent la syntaxe SQL-92.
- Ce n'est pas un commentaire, il est une réponse. Cette question a 14 réponses, dont 3 avec plus de 50 points. Quel est votre commentaire à ajouter? Il me semble que c'est un troll sur SQL-89 vs SQL-92
- J'étais en soulignant les noms officiels des syntaxes différentes. Aucune réponse dit explicitement le nom au complet, j'ai donc décidé d'ajouter ces commentaires. Cependant, mon commentaire n'a pas répondu à la question réelle, donc j'ai ajouté comme commentaire, non pas comme une réponse. (Haute voté réponses des allégations telles que "INNER JOIN est syntaxe ANSI" et "jointure implicite syntaxe ANSI est plus vieux" qui ne dit rien du tout parce que les deux syntaxes différentes ANSI syntaxes.)
Vous devez vous connecter pour publier un commentaire.
INNER JOIN
est syntaxe ANSI que vous devriez utiliser.Il est généralement considéré comme plus lisible, surtout quand vous vous joignez à beaucoup de tables.
Il peut aussi être facilement remplacés par un
OUTER JOIN
chaque fois qu'un besoin se fait sentir.La
WHERE
syntaxe est plus le modèle relationnel orienté.À la suite de deux tables
JOIN
ed est un produit cartésien des tables pour lesquelles un filtre est appliqué, ce qui sélectionne uniquement les lignes avec les colonnes de jointure de correspondance.Il est plus facile de voir cela avec le
WHERE
syntaxe.Comme pour ton exemple, dans MySQL (et en SQL, en général), ces deux requêtes sont synonymes.
Également noter que MySQL a aussi un
STRAIGHT_JOIN
clause.L'utilisation de cette clause, vous pouvez contrôler la
JOIN
ordre: la table qui est analysé dans la boucle externe et que l'on est dans la boucle interne.Vous ne pouvez pas contrôler ce dans MySQL à l'aide de
WHERE
syntaxe.Oracle
,SQL Server
,MySQL
etPostgreSQL
— oui. Pour les autres systèmes, sans doute, aussi, mais il vaut mieux vérifier.WHERE
clause est également conforme à la norme ANSI.@Bill Karwin
:JOIN
mot-clé n'a pas été une partie de standards propriétaires jusqu'à ce que le passé plus récent qu'il peut sembler. Il a fait son chemin dansOracle
uniquement dans la version9
et enPostgreSQL
dans la version7.2
(tous deux sortis en2001
). L'apparition de ce mot-clé a été une partie deANSI
adoption du standard, et c'est pourquoi ce mot-clé est généralement associée àANSI
, malgré le fait que ce dernier prend en charge la virgule comme un synonyme deCROSS JOIN
ainsi.WHERE
de l'alinéa (sans conditions, une jointure est équivalent à une jointure croisée, comme vous l'avez dit). ANSI SQL-92 a ajouté leJOIN
de mots clés et connexes de la syntaxe, mais par des virgules de la syntaxe de style est toujours pris en charge pour la rétro-compatibilité.JOIN
syntaxe dès 1994.join on
au lieu d'utiliserWHERE
?D'autres ont souligné que la JOINTURE INTERNE contribue à la lisibilité de l'homme, et c'est une priorité absolue; je suis d'accord. Laissez-moi vous expliquer pourquoi la syntaxe de jointure est plus lisible.
De base d'une requête SELECT est ceci:
La clause SELECT nous dit ce nous sommes de retour; la clause from nous dit où nous sommes en train de partir, et la clause where nous dit qui ceux que nous obtenons.
JOINTURE est une déclaration sur les tables, la façon dont ils sont liés entre eux (sur le plan conceptuel, en fait, dans une seule table). Toute requête éléments qui permettent de contrôler les tables où nous sommes de plus en plus de choses à partir d' - sémantiquement appartiennent à la clause from (et bien sûr, c'est là que JOINDRE des éléments go). Mettre de rejoindre éléments dans la clause where débordait du qui et la où-à partir de; c'est pourquoi la syntaxe de JOINTURE est préféré.
Appliquer des instructions conditionnelles dans les SUR /OÙ
Ici, j'ai expliqué à propos de la logique de traitement de la requête de mesures.
De référence : à l'Intérieur de Microsoft® SQL Server™ 2005 T-SQL d'Interrogation
Editeur: Microsoft Press
Pub Date: 07 Mars 2006
Imprimer ISBN-10: 0-7356-2313-9
Imprimer ISBN-13: 978-0-7356-2313-2
Pages: 640
À l'intérieur de Microsoft® SQL Server™ 2005 T-SQL d'Interrogation
Le premier aspect notable de SQL qui est différent des autres langages de programmation est l'ordre dans lequel le code est traité. Dans la plupart des langages de programmation, le code est traité dans l'ordre dans lequel il est écrit. En SQL, la première clause qui est traité dans la clause from, tandis que la clause SELECT, qui apparaît d'abord, est traitée presque dernier.
Chaque étape génère une table virtuelle qui est utilisée comme entrée pour l'étape suivante. Ces tables virtuelles ne sont pas disponibles à l'appelant (le client demande ou de la requête externe). Seul le tableau généré par la dernière étape est retourné à l'appelant. Si une clause n'est pas spécifié dans une requête, l'étape correspondante est simplement ignorée.
Brève Description de la Logique de Traitement de Requête Phases
Ne vous inquiétez pas trop si la description des étapes ne semble pas faire beaucoup de sens pour l'instant. Ces sont fournies à titre de référence. Les Sections qui viennent après le scénario d'exemple, permettra de couvrir les étapes plus en détail.
DE: UN produit Cartésien (cross join) est réalisée entre les deux premières tables dans la clause from, et comme un résultat, table virtuelle VT1 est généré.
SUR: Le filtre est appliqué à VT1. Seules les lignes pour lesquelles la
<join_condition>
est VRAI, sont insérés pour VT2.EXTERNE (join): Si une JOINTURE EXTERNE est indiqué (par opposition à une JOINTURE CROISÉE ou une JOINTURE INTERNE), les lignes de la préservés de la table ou les tables pour lesquelles un match n'a pas été trouvé, sont ajoutés les lignes de VT2 que les rangées extérieures, générant VT3. Si plus de deux tables apparaissent dans la clause from, les étapes 1 à 3 sont applicables à plusieurs reprises entre le résultat de la jointure dernière et de la prochaine table dans la clause from jusqu'à ce que toutes les tables sont traitées.
OÙ: La OÙ le filtre est appliqué à VT3. Seules les lignes pour lesquelles la
<where_condition>
est VRAI, sont insérés sur VT4.GROUPE PAR: Les lignes de VT4 sont disposées par groupes en fonction de la liste des colonnes spécifiées dans la clause GROUP BY. VT5 est généré.
CUBE | CUMULATIF: super-groupes (groupes de groupes) sont ajoutés les lignes de VT5, générant VT6.
: L'AYANT filtre est appliqué à VT6. Seuls les groupes pour lesquels l'
<having_condition>
est VRAI, sont insérés pour VT7.SÉLECTIONNEZ: La liste de sélection est traitée, générant VT8.
DISTINCTES: les Doublons sont supprimés à partir de VT8. VT9 est généré.
COMMANDE PAR: Les lignes de VT9 sont triés en fonction de la liste des colonnes spécifiées dans la clause ORDER BY. Un curseur est généré (VC10).
HAUT: Le nombre ou le pourcentage spécifié de lignes est sélectionné à partir du début de VC10. Tableau VT11 est généré et est retourné à l'appelant.
Par conséquent, (INNER JOIN) SUR filtre les données (les données de comptage de VT sera réduit ici même) avant d'appliquer la clause where. Les ultérieur des conditions de jointure sera exécuté avec les données filtrées qui améliore les performances. Après que seul le OÙ la condition s'appliquera conditions de filtre.
(Application des instructions conditionnelles dans les SUR /OÙ ne fera pas beaucoup de différence dans quelques cas. Cela dépend du nombre de tables que vous avez rejoint et le nombre de lignes disponibles dans chacune des tables de jointure)
La jointure implicite syntaxe ANSI est plus âgé, moins évidente et n'est pas recommandé.
En outre, l'algèbre relationnelle permet l'interchangeabilité des prédicats dans la
WHERE
de la clause et de laINNER JOIN
, de sorte que mêmeINNER JOIN
requêtes avecWHERE
clauses peuvent avoir les prédicats rearrranged par l'optimiseur.Je vous recommande d'écrire les requêtes dans la plupart des readble façon possible.
Parfois, cela inclut la fabrication
INNER JOIN
relativement "incomplet" et de mettre certains de ces critères dans lesWHERE
tout simplement pour faire les listes de critères de filtrage plus facilement maintenable.Par exemple, au lieu de:
Écrire:
Mais elle dépend, bien sûr.
Implicite des jointures (qui est ce que votre première requête est connu comme) deviennent beaucoup beaucoup plus confus, difficile à lire, et difficiles à maintenir une fois que vous avez besoin pour commencer à ajouter plus de tables à votre requête. Imaginer faire la même requête et le type de jointure sur quatre ou cinq tables différentes ... c'est un cauchemar.
À l'aide d'un explicite join (votre deuxième exemple) est beaucoup plus lisible et facile à entretenir.
Je vous ferais également remarquer que l'utilisation de l'ancienne syntaxe est plus sujette à l'erreur. Si vous utilisez des jointures internes, sans une clause, vous obtiendrez une erreur de syntaxe. Si vous utilisez l'ancienne syntaxe et d'oublier l'une des conditions de jointure dans la clause where, vous obtiendrez une jointure croisée. Les développeurs souvent résoudre ce problème en ajoutant le mot-clé distinct (plutôt que de fixer le rejoindre parce qu'ils ne réalisent pas le rejoindre lui-même est cassé) qui peuvent apparaître à guérir le problème, mais va ralentir la requête considérablement.
De plus pour l'entretien, si vous avez une jointure croisée dans l'ancienne syntaxe, comment le mainteneur savoir si vous en avez un (il y a des situations où les jointures croisées sont nécessaires) ou si c'était un accident qui doit être fixée?
Permettez-moi de vous pointer à cette question pour voir pourquoi l'implicite de la syntaxe est mauvaise si vous utilisez gauche rejoint.
Sybase *= Ansi Standard avec 2 externes différentes tables pour la même table interne
Plus (personnels coup de gueule ici), le standard à l'aide de l'explicite rejoint plus de 20 ans, ce qui signifie implicite de la syntaxe de jointure a été dépassée pendant ces 20 années. Voulez-vous écrire le code de l'application à l'aide de la syntaxe qui a été dépassée pendant 20 ans? Pourquoi voulez-vous écrire de code de base de données qui est?
HAVING
qui a été "dépassé" depuis SQL commencé à prendre en charge les tables dérivées. Je remarque aussi que vous n'utilisez pasNATURAL JOIN
même si je dirais qu'elle a faitINNER JOIN
"dépassé". Oui, vous avez vos raisons (pas besoin de les citer à nouveau ici!): mon point est, ceux qui aiment l'aide de l'ancienne syntaxe ont leurs raisons et l'âge relatif de la syntaxe est de si peu d'importance.WHERE
forme n'est plus dans la norme, mais simplement que laJOIN
forme (plus probable et par la plupart des comptes destinés à être "mieux") a été autour pendant beaucoup de temps pour réduire de manière significative, si ce n'est, d'éliminer les raisons (c'est à dire de travailler avec le code existant) d'utiliser l'ancien formulaire.Ils ont une autre forme lisible par l'homme de sens.
Toutefois, selon l'optimiseur de requête, ils peuvent avoir le même sens pour la machine.
Vous devriez toujours code soit lisible.
C'est-à-dire, si c'est un construit-dans la relation, l'utilisation explicite de jointure. si vous faites une comparaison sur que faiblement sur les données, utilisez la clause where.
SQL:2003 modifié certaines règles de priorité si une instruction de JOINTURE est prioritaire sur une "virgule" de jointure. Cet état de fait peut modifier les résultats de votre requête, selon la façon dont il est installé. Cette cause de certains problèmes pour certaines personnes lorsque MySQL 5.0.12 passé à adhérer à la norme.
Donc dans votre exemple, vos requêtes fonctionnent de la même. Mais si vous avez ajouté un troisième tableau:
SELECT ... from table1, table2 REJOINDRE tableau3 SUR ... OÙ ...
Avant MySQL 5.0.12, table1 et table2 serait rejoint d'abord, puis tableau3. Maintenant (5.0.12 et sur), table2 et tableau3 sont rejoint d'abord, puis de table1. Il n'est pas toujours changer les résultats, mais il peut et on ne peut même pas s'en rendre compte.
Je n'ai jamais utiliser la "virgule" de la syntaxe de plus, en optant pour le second exemple. C'est beaucoup plus lisible de toute façon, les conditions de JOINTURE sont avec les Jointures ne sont pas séparées dans une requête distincte de la section.
Je sais que vous parlez de MySQL, mais de toute façon:
Dans Oracle 9 jointures explicites et implicites rejoint serait de générer des différents plans d'exécution. Autant que je sache qui a été résolu dans Oracle 10+: il n'y a pas plus de différence.
ANSI syntaxe de jointure est nettement plus portables.
Je vais à travers une mise à niveau de Microsoft SQL Server, et j'aimerais également mentionner que l' =* et *= syntaxe des jointures en SQL Server n'est pas prise en charge (sans mode de compatibilité) pour sql server 2005 et versions ultérieures.
*=
et=*
n'ont jamais été ANSI et n'ont jamais été une bonne notation. C'est pourquoi, en était besoin-pour les Jointures EXTERNES en l'absence de les sous-sélections (qui a été ajouté dans le même temps, de sorte qu'ils ne sont pas réellement nécessaires en CROIX & Jointures internes.)