33 votes

INNER JOIN contre les noms de table multiples dans "FROM".

Duplicata possible :
INNER JOIN versus clause WHERE - une différence ?

Quelle est la différence entre une requête INNER JOIN et une requête de jointure implicite (énumérant plusieurs tables après le mot-clé FROM) ? Par exemple :

Étant donné les deux tableaux suivants :

CREATE TABLE Statuses(
  id INT PRIMARY KEY,
  description VARCHAR(50)
);
INSERT INTO Statuses VALUES (1, 'status');

CREATE TABLE Documents(
  id INT PRIMARY KEY,
  statusId INT REFERENCES Statuses(id)
);
INSERT INTO Documents VALUES (9, 1);

Quelle est la différence entre ces deux requêtes SQL ? D'après les tests que j'ai effectués, elles renvoient le même résultat. Font-elles la même chose ? Y a-t-il des situations où elles renvoient des ensembles de résultats différents ?

SELECT s.description FROM Documents d, Statuses s WHERE d.statusId = s.id AND d.id = 9;

SELECT s.description FROM Documents d INNER JOIN Statuses s ON d.statusId = s.id WHERE d.id = 9;

14voto

Jordan Points 12780

Si vous le faites de la première manière, les personnes de moins de 30 ans vont probablement se moquer de vous, mais tant que vous faites une jointure interne, elles produisent le même résultat et l'optimiseur générera le même plan d'exécution (du moins pour autant que j'aie pu le dire).

Cela suppose bien sûr que la clause where de la première requête est celle que vous joindrez dans la deuxième requête.

Ceci sera probablement fermé en tant que duplicata, btw.

13voto

HLGEM Points 54641

Il n'y a aucune raison d'utiliser une jointure implicite (celle avec les virgules). Oui, pour les jointures internes, les résultats seront les mêmes. Cependant, elle est sujette à des jointures croisées par inadvertance, en particulier dans les requêtes complexes, et elle est plus difficile à maintenir car la syntaxe des jointures externes gauche/droite (dépréciée dans SQL Server, où elle ne fonctionne pas correctement à l'heure actuelle) diffère d'un fournisseur à l'autre. Puisque vous ne devriez pas mélanger les jointures implicites et explicites dans la même requête (vous pouvez obtenir des résultats erronés), le fait de devoir changer quelque chose en une jointure gauche signifie réécrire la requête entière.

8voto

danwyand Points 664

L'avantage de la deuxième méthode est qu'elle permet de séparer la condition de jointure (on ...) de la condition de filtrage (where ...). Cela peut aider à rendre l'intention de la requête plus lisible.

La condition de jointure sera généralement plus descriptive de la structure de la base de données et de la relation entre les tables. Par exemple, la table des salaires est liée à la table des employés par la colonne EmployeeID, et les requêtes impliquant ces deux tables seront probablement toujours jointes sur cette colonne.

La condition de filtrage est plus descriptive de la tâche spécifique exécutée par la requête. Si la requête est FindRichPeople, la clause where pourrait être "where salaries.Salary > 1000000"... cela décrit la tâche à accomplir, pas la structure de la base de données.

Notez que le compilateur SQL ne voit pas les choses de cette façon... s'il décide qu'il sera plus rapide de faire une jointure croisée puis de filtrer les résultats, il fera une jointure croisée et filtrera les résultats. Il ne se soucie pas de ce qui est dans la clause ON et de ce qui est dans la clause WHERE. Mais cela ne se produit généralement pas si la clause ON correspond à une clé étrangère ou si elle est liée à une clé primaire ou à une colonne indexée. Pour ce qui est de fonctionner correctement, elles sont identiques ; pour ce qui est d'écrire un code lisible et facile à maintenir, la deuxième méthode est probablement un peu meilleure.

3voto

MUG4N Points 5011

Il n'y a pas de différence, pour autant que je sache, la seconde avec la jointure interne est la nouvelle façon d'écrire de telles déclarations et la première l'ancienne méthode.

3voto

Feisty Mango Points 7113

La première effectue un produit cartésien sur tous les enregistrements de ces deux tables puis filtre par la clause where.

La seconde jointure ne concerne que les enregistrements qui répondent aux exigences de votre clause ON.

EDIT : Comme d'autres l'ont indiqué, le moteur d'optimisation se chargera d'une tentative sur un produit cartésien et aboutira plus ou moins à la même requête.

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