297 votes

SQL a laissé vs joindre plusieurs tables de la ligne ?

La plupart des dialectes SQL acceptent les deux requêtes suivantes :

Maintenant évidemment lorsque vous avez besoin d’une jointure externe, la seconde syntaxe est nécessaire. Mais lorsque vous effectuez une jointure interne pourquoi devrais je préfère la seconde syntaxe à la première (ou vice-versa) ?

355voto

Lasse V. Karlsen Points 148037

L'ancienne syntaxe, avec juste la liste des tables, et à l'aide de l' WHERE clause de spécifier les critères de jointure, est désapprouvées dans la plupart des bases de données modernes.

Ce n'est pas juste pour le show, l'ancienne syntaxe a la possibilité d'être ambigu lorsque vous utilisez à la fois INTERNE et EXTERNE s'inscrit dans la même requête.

Laissez-moi vous donner un exemple.

Supposons que vous disposez de 3 tables dans votre système:

Company
Department
Employee

Chaque table contient plusieurs lignes, liés ensemble. Vous avez plusieurs sociétés, et chaque entreprise peut avoir plusieurs ministères, et chaque ministère peut avoir plusieurs employés.

Ok, alors maintenant, vous voulez faire le suivi:

Liste de toutes les entreprises, et d'inclure tous leurs ministères, et de tous leurs employés. Notez que certaines entreprises n'ont pas de ministères, mais assurez-vous d'inclure aussi bien. Assurez-vous de récupérer uniquement les ministères qui ont des employés, mais toujours la liste de toutes les entreprises.

Si vous faites cela:

SELECT * -- for simplicity
FROM Company, Department, Employee
WHERE Company.ID *= Department.CompanyID
  AND Department.ID = Employee.DepartmentID

Notez que la dernière est une jointure interne, afin de remplir les critères que vous voulez seulement les ministères avec les gens.

Ok, donc ce qui se passe maintenant. Eh bien, le problème est, il dépend du moteur de base de données, l'optimiseur de requête, les index et les statistiques de la table. Laissez-moi vous expliquer.

Si l'optimiseur de requête détermine que la façon de le faire est d'abord de l'entreprise, puis de trouver les ministères, et ensuite faire une jointure interne avec les employés, vous n'allez pas pour obtenir toutes les sociétés qui n'ont pas les ministères.

La raison pour cela est que l' WHERE clause détermine les lignes de la fin dans le résultat final, pas de pièces individuelles de lignes.

Et dans ce cas, en raison de la jointure gauche, le Département.ID de colonne est NULL, et donc quand il s'agit de la JOINTURE INTERNE à l'Employé, il n'y a aucun moyen de répondre à cette contrainte pour le Salarié ligne, et afin de ne pas apparaître.

D'autre part, si l'optimiseur de requête décide de s'attaquer au ministère de l'employé rejoindre d'abord, et ensuite faire un left join avec les entreprises, vous les verrez.

Ainsi, la vieille syntaxe est ambigu. Il n'y a aucune façon de préciser ce que vous voulez, sans traiter avec les indicateurs de requête, et certaines bases de données ont aucun moyen.

Entrez la nouvelle syntaxe, avec cela, vous pouvez choisir.

Par exemple, si vous voulez toutes les entreprises, comme la description du problème, ce est ce que vous écrivez:

SELECT *
FROM Company
     LEFT JOIN (
         Department INNER JOIN Employee ON Department.ID = Employee.DepartmentID
     ) ON Company.ID = Department.CompanyID

Ici, vous indiquez que vous souhaitez que le ministère de l'employé rejoindre à faire une jointure, puis à gauche et rejoindre les résultats avec les entreprises.

En outre, disons que vous voulez seulement les ministères qui contient la lettre X dans leur nom. Encore une fois, avec de vieux style de jointures, vous risquez de perdre de l'entreprise ainsi, si il n'a pas de départements avec un X dans son nom, mais avec la nouvelle syntaxe, vous pouvez faire ceci:

SELECT *
FROM Company
     LEFT JOIN (
         Department INNER JOIN Employee ON Department.ID = Employee.DepartmentID
     ) ON Company.ID = Department.CompanyID AND Department.Name LIKE '%X%'

Cette clause supplémentaire est utilisé pour le rejoindre, mais n'est pas un filtre pour l'ensemble de la ligne. Ainsi, la ligne peut apparaître avec la société de l'information, mais qui peuvent avoir des valeurs nulles dans tout le département et l'employé colonnes de cette ligne, car il n'y a pas de département avec un X dans son nom de cette société. C'est dur avec l'ancienne syntaxe.

C'est pourquoi, parmi d'autres vendeurs, Microsoft a retiré de l'ancienne syntaxe de jointure externe, mais pas la vieille syntaxe inner join, depuis SQL Server 2005 et vers le haut. La seule façon de parler à une base de données fonctionnant sur le Microsoft SQL Server 2005 ou 2008, en utilisant le style ancien de la syntaxe de jointure externe, est de mettre cette base de données en mode de compatibilité 8.0 (alias SQL Server 2000).

En outre, à l'ancienne, en jetant un tas de tables à l'optimiseur de requête, avec un tas de clauses where, qui revenait à dire "vous êtes ici, faire le mieux possible". Avec la nouvelle syntaxe, l'optimiseur de requête a moins de travail à faire afin de déterminer quelles parties vont ensemble.

Donc là vous l'avez.

La GAUCHE et la JOINTURE INTERNE est la vague de l'avenir.

18voto

Andomar Points 115404

Les conditions de garde de syntaxe de jointure près de la table, à qu'ils s’appliquent. Ceci est particulièrement utile lorsque vous rejoignez une grande quantité de tables.

Par ailleurs, vous pouvez effectuer une jointure externe avec la première syntaxe trop :

Ou

Ou

14voto

Dwight T Points 544

La première manière est la norme ancienne. La deuxième méthode a été introduite dans SQL-92, http://en.wikipedia.org/wiki/SQL. La norme complète peut être consultée à l' http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt .

Il a fallu de nombreuses années avant que la base de données de sociétés ont adopté la norme SQL-92.

Donc la raison pour laquelle la deuxième méthode est préféré, c'est le SQL standard selon les normes ANSI et ISO comité.

11voto

HLGEM Points 54641

La deuxième est préféré parce qu'il est beaucoup moins susceptible d'entraîner une altération de la croix rejoindre en oubliant de mettre dans la clause where. Une jointure avec aucune clause va échouer la vérification de la syntaxe, un vieux style de jointure sans clause where ne manquera pas, il va faire une jointure croisée.

De plus, lorsque vous plus tard avoir une jointure gauche, il est utile pour l'entretien qu'ils soient tous dans la même structure. Et l'ancienne syntaxe n'est pas à jour depuis 1992, il est bien temps d'arrêter de l'utiliser.

En Plus, j'ai constaté que beaucoup de gens qui utilisent exclusivement la première syntaxe ne comprends pas vraiment la rejoint et la compréhension des jointures est essentiel pour obtenir des résultats corrects lors de l'interrogation.

6voto

Alan G Points 31

Je pense qu’il y a de bonnes raisons à cette page d’adopter la deuxième méthode-à l’aide de jointures explicites. Le pneu est cependant que lorsque les critères de jointure sont supprimées de la clause WHERE, il devient beaucoup plus facile de voir les autres critères de sélection dans la clause WHERE.

Dans les instructions SELECT vraiment complexes, il devient beaucoup plus facile pour un lecteur à comprendre ce qui se passe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X