Comprendre les concepts et la syntaxe des jointures

Effectué

La méthode la plus fondamentale et la plus courante pour combiner les données de plusieurs tables est d’utiliser une opération de jointure. Certaines personnes pensent que JOIN est une clause distincte dans une instruction SELECT, mais d’autres pensent qu’elle fait partie de la clause FROM. Ce module considère principalement qu’elle fait partie de la clause FROM. Dans ce module, nous découvrons comment la clause FROM dans une instruction T-SQL SELECT crée des tables virtuelles intermédiaires qui sont ensuite consommées par des phases ultérieures de la requête.

Clause FROM et tables virtuelles

Si vous avez appris l’ordre logique des opérations qui sont effectuées quand SQL Server traite une requête, vous avez vu que la clause FROM d’une instruction SELECT est la première clause traitée. Cette clause détermine la ou les tables qui constituent la source des lignes de la requête. FROM peut référencer une seule table ou réunir plusieurs tables comme source de données de votre requête. Vous pouvez considérer que la clause FROM crée et remplit une table virtuelle. Cette table virtuelle contient la sortie de la clause FROM et est utilisée par les clauses de l’instruction SELECT qui sont appliquées par la suite, par exemple, la clause WHERE. À mesure que vous ajoutez des fonctionnalités supplémentaires, comme des opérateurs de jointure, à une clause FROM, déterminez si l’objectif des éléments de la clause FROM est d’ajouter ou de supprimer des lignes dans la table virtuelle.

La table virtuelle créée par une clause FROM se limite à une entité logique. Dans SQL Server, aucune table physique n’est créée, qu’elle soit persistante ou temporaire, pour contenir les résultats de la clause FROM, car elle est passée à la clause WHERE ou à d’autres parties de la requête.

La table virtuelle créée par la clause FROM contient des données de toutes les tables jointes. Pour simplifier, prenez les résultats comme des ensembles et conceptualisez les résultats de jointure dans un diagramme de Venn.

A Venn diagram showing the set of an Employee table joined to a SalesOrder table

Tout au long de son histoire, le langage T-SQL a été développé pour refléter les changements des normes ANSI (American National Standards Institute) du langage SQL. C’est dans la syntaxe des jointures d’une clause FROM que ces changements sont les plus visibles. Dans la norme ANSI SQL-89, les jointures sont spécifiées en ajoutant plusieurs tables dans la clause FROM sous forme de liste séparée par des virgules. Le filtrage pour déterminer les lignes à ajouter est effectué dans la clause WHERE, de la façon suivante :

SELECT p.ProductID, m.Name AS Model, p.Name AS Product
FROM SalesLT.Product AS p, SalesLT.ProductModel AS m
WHERE p.ProductModelID = m.ProductModelID;

Cette syntaxe est toujours prise en charge par SQL Server, mais en raison de la complexité de la représentation des filtres pour les jointures complexes, elle n’est pas recommandée. Par ailleurs, si une clause WHERE est omise par inadvertance, les jointures de type ANSI SQL-89 peuvent facilement devenir des produits cartésiens et retourner un nombre excessif de lignes de résultats, entraînant ainsi des problèmes de performances et éventuellement des résultats incorrects.

Quand vous apprenez à écrire des requêtes multitables dans T-SQL, vous devez comprendre le concept des produits cartésiens. En mathématiques, un produit cartésien est le produit de deux ensembles. Le produit d’un ensemble de deux éléments et d’un ensemble de six éléments est un ensemble de 12 éléments (6 x 2). Chaque élément d’un ensemble est combiné à chaque élément de l’autre ensemble. Dans l’exemple ci-dessous, nous avons un ensemble de noms avec deux éléments et un ensemble de produits avec trois éléments. Le produit cartésien combine chaque nom à chaque produit, ce qui donne six éléments.

Cartesian product

Dans les bases de données, un produit cartésien est le résultat de la combinaison de chaque ligne d’une table avec chaque ligne d’une autre table. Le produit d’une table de 10 lignes et d’une table de 100 lignes est un jeu de résultats de 1 000 lignes. Le résultat sous-jacent d’une opération de jointure est un produit cartésien, mais pour la plupart des requêtes T-SQL, un produit cartésien n’est pas le résultat souhaité. Dans T-SQL, un produit cartésien se produit quand deux tables d’entrée sont jointes sans prendre en compte les relations entre elles. En l’absence d’informations sur les relations, le processeur de requêtes SQL Server retourne toutes les combinaisons de lignes possibles. Bien que ce résultat puisse avoir des applications pratiques, par exemple, la génération de données de test, il n’est généralement pas utile et peut avoir des répercussions graves sur les performances.

Avec l’avènement de la norme ANSI SQL-92, la prise en charge des mots clés JOIN et ON a été ajoutée. T-SQL prend également en charge cette syntaxe. Les jointures sont représentées dans la clause FROM à l’aide de l’opérateur de jointure approprié. La relation logique entre les tables, qui devient un prédicat de filtre, est spécifiée dans la clause ON.

L’exemple suivant réitère la requête précédente avec la syntaxe plus récente :

SELECT p.ProductID, m.Name AS Model, p.Name AS Product
FROM SalesLT.Product AS p
JOIN SalesLT.ProductModel AS m
    ON p.ProductModelID = m.ProductModelID;

Notes

La syntaxe ANSI SQL-92 rend plus difficile la création accidentelle de produits cartésiens. Une fois que le mot clé JOIN a été ajouté, une erreur de syntaxe est générée si une clause ON est manquante, sauf si la jointure spécifiée est une jointure croisée.