Database
 sql >> Base de données >  >> RDS >> Database

Tutoriel sur les jointures SQL

Une jointure SQL est l'endroit où vous exécutez une requête qui joint plusieurs tables.

Ce didacticiel sur les jointures SQL présente des exemples de base de jointures SQL, ainsi qu'une introduction aux différents types de jointures.

Types de jointure SQL

La norme ANSI SQL spécifie cinq types de jointures, comme indiqué dans le tableau suivant.

Type de jointure Description

INNER JOIN
Renvoie des lignes lorsqu'il y a au moins une ligne dans les deux tables qui correspondent à la condition de jointure.

LEFT OUTER JOIN
ou alors
LEFT JOIN
Renvoie les lignes contenant des données dans le tableau de gauche (à gauche du JOIN mot-clé), même s'il n'y a pas de lignes correspondantes dans le bon tableau.

RIGHT OUTER JOIN
ou alors
RIGHT JOIN
Renvoie les lignes qui ont des données dans la bonne table (à droite du JOIN mot-clé), même s'il n'y a pas de lignes correspondantes dans le tableau de gauche.

FULL OUTER JOIN
ou alors
FULL JOIN
Renvoie toutes les lignes, tant qu'il y a des données correspondantes dans l'une des tables.
CROSS JOIN Renvoie les lignes qui combinent chaque ligne du premier tableau avec chaque ligne du second tableau.

Il existe également d'autres termes pour diverses opérations de jointure, telles que les suivantes :

Rejoindre Description
Auto-jointure Lorsqu'une table se joint à elle-même.
Jointure naturelle Une jointure implicite basée sur les colonnes communes des deux tables jointes.
Équi-jointure Une jointure contenant uniquement des comparaisons d'égalité dans le prédicat de jointure.

Syntaxe de jointure SQL

Les jointures internes peuvent être spécifiées soit dans le FROM ou WHERE clauses. Les jointures externes et les jointures croisées peuvent être spécifiées dans le FROM clause seulement.

Pour créer une jointure SQL dans le FROM clause, faites quelque chose comme ceci :

SELECT *
FROM Table1 < JoinType > Table2 [ ON ( JoinCondition ) ]

JoinType spécifie le type de jointure effectuée et JoinCondition définit le prédicat à évaluer pour chaque paire de lignes jointes.

Pour spécifier une jointure dans WHERE clause, faites quelque chose comme ceci :

SELECT *
FROM Table1, Table2 [ WHERE ( JoinCondition ) ]

Encore une fois, JoinCondition définit le prédicat à évaluer pour chaque paire de lignes jointes.

De plus, tout ce qui est entre crochets ([] ) est facultatif.

Exemples de tableaux pour les exemples de ce didacticiel

La plupart des exemples de ce didacticiel effectuent des jointures sur les deux tables suivantes.

Les PetTypes tableau :

+-------------+-----------+
| PetTypeId   | PetType   |
|-------------+-----------|
| 1           | Bird      |
| 2           | Cat       |
| 3           | Dog       |
| 4           | Rabbit    |
+-------------+-----------+
(4 rows affected)

Les Pets tableau :

+---------+-------------+-----------+-----------+------------+
| PetId   | PetTypeId   | OwnerId   | PetName   | DOB        |
|---------+-------------+-----------+-----------+------------|
| 1       | 2           | 3         | Fluffy    | 2020-11-20 |
| 2       | 3           | 3         | Fetch     | 2019-08-16 |
| 3       | 2           | 2         | Scratch   | 2018-10-01 |
| 4       | 3           | 3         | Wag       | 2020-03-15 |
| 5       | 1           | 1         | Tweet     | 2020-11-28 |
| 6       | 3           | 4         | Fluffy    | 2020-09-17 |
| 7       | 3           | 2         | Bark      | NULL       |
| 8       | 2           | 4         | Meow      | NULL       |
+---------+-------------+-----------+-----------+------------+
(8 rows affected)

La jointure interne

Le SQL INNER JOIN renvoie des lignes lorsqu'il y a au moins une ligne dans les deux tables qui correspondent à la condition de jointure.

SELECT
    Pets.PetName,
    PetTypes.PetType
FROM Pets
INNER JOIN PetTypes
ON Pets.PetTypeId = PetTypes.PetTypeId;

Résultat :

-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+
(8 rows affected)

Pour spécifier une jointure interne dans le FROM clause, nous utilisons INNER JOIN . Nous utilisons également le ON mot-clé pour définir le prédicat à évaluer pour chaque paire de lignes jointes.

Quel que soit le type de jointure, nous qualifions nos noms de colonne avec les noms de table. La raison pour laquelle nous faisons cela est d'éviter toute ambiguïté concernant les noms de colonne entre les tables. Les deux tables peuvent avoir des colonnes du même nom (comme dans notre exemple), et dans de tels cas, le SGBD ne saura pas à quelle colonne vous faites référence. Préfixer les noms de colonne avec leurs noms de table garantit que vous faites référence à la bonne colonne et évite toute erreur pouvant résulter d'une ambiguïté sur la colonne à laquelle vous faites référence.

Dans cet exemple, les deux tables ont un PetTypeId colonne. Le Pets.PetTypeId colonne est une clé étrangère vers PetTypes.PetTypeId colonne, qui est la clé primaire de cette table.

Dans cet exemple, nous pouvons voir que tous les animaux sont renvoyés, mais que tous les types d'animaux ne sont pas renvoyés. Il n'y a pas de lapins dans les Pets table, et donc les Rabbits le type d'animal n'est pas renvoyé.

La raison pour laquelle les Rabbits type n'est pas renvoyé parce que le INNER JOIN ne renvoie des lignes que lorsqu'il y a au moins une ligne dans les deux tables qui correspondent à la condition de jointure. Dans ce cas, Rabbits est dans une seule table (le PetTypes tableau).

Notez que le type de jointure est facultatif. Par conséquent, la plupart (sinon tous) les SGBD vous permettent d'omettre le INNER mot-clé. Lorsque vous omettez ceci (c'est-à-dire ne spécifiez que JOIN ), il est supposé être une jointure interne.

Par conséquent, nous pourrions réécrire l'exemple ci-dessus :

SELECT
    Pets.PetName,
    PetTypes.PetType
FROM Pets
JOIN PetTypes
ON Pets.PetTypeId = PetTypes.PetTypeId;

De plus, comme pour toute instruction SQL, le FROM clause peut être sur une ligne entière si vous préférez :

SELECT
    Pets.PetName,
    PetTypes.PetType
FROM Pets JOIN PetTypes ON Pets.PetTypeId = PetTypes.PetTypeId;

Alias

Il est courant d'utiliser des alias de table lors de l'exécution de jointures SQL. Les alias aident à rendre le code plus concis et plus facile à lire.

Par conséquent, nous pourrions remplacer l'exemple précédent par ceci :

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;

Résultat :

-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+
(8 rows affected)

L'équi-jointure

La jointure ci-dessus peut également être appelée équi-jointure . Une équi-jointure est une jointure contenant uniquement des comparaisons d'égalité dans le prédicat de jointure.

Voici une autre façon d'écrire la jointure ci-dessus :

SELECT
    p.PetName,
    pt.PetType
FROM 
    Pets p, 
    PetTypes pt
WHERE p.PetTypeId = pt.PetTypeId;

Résultat :

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+

Ceci est un exemple de spécification d'une jointure interne dans WHERE clause. Nous avons simplement fourni une liste des tables séparées par des virgules, puis un WHERE état. Si nous avions omis le WHERE condition, nous aurions fini avec un CROSS JOIN .

De nombreux débutants trouvent la syntaxe ci-dessus beaucoup plus facile à comprendre que le INNER JOIN syntaxe. N'hésitez pas à utiliser cette syntaxe si vous préférez, cependant, sachez que la plupart des professionnels de SQL préfèrent utiliser le INNER JOIN syntaxe de l'exemple précédent.

Voir SQL Inner Join pour plus d'exemples, y compris une jointure interne qui joint 3 tables.

La bonne jointure

Aussi connu sous le nom de RIGHT OUTER JOIN , le RIGHT JOIN renvoie les lignes qui ont des données dans la bonne table (à droite du JOIN mot-clé), même s'il n'y a pas de lignes correspondantes dans le tableau de gauche.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
RIGHT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;

Résultat :

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Tweet     | Bird      |
| Fluffy    | Cat       |
| Scratch   | Cat       |
| Meow      | Cat       |
| Fetch     | Dog       |
| Wag       | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

Dans ce cas, nous avons un PetType supplémentaire valeur – Rabbit – même s'il n'y a pas d'animal dans le Pets tableau de ce type. Cela se traduit par un NULL valeur dans le PetName colonne contre Rabbit .

Voir SQL Right Join pour plus d'exemples, y compris une jointure à droite qui joint 3 tables.

La jointure gauche

Aussi connu sous le nom de LEFT OUTER JOIN , le SQL LEFT JOIN renvoie les lignes contenant des données dans le tableau de gauche (à gauche du JOIN mot-clé), même s'il n'y a pas de lignes correspondantes dans le bon tableau.

C'est l'opposé du RIGHT JOIN .

Si nous modifions l'exemple précédent pour utiliser une jointure gauche, nous obtenons le résultat suivant.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
LEFT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;

Résultat :

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+
(8 rows affected)

Dans ce cas particulier, nos résultats sont les mêmes qu'avec la jointure interne.

Cependant, si nous échangeons l'ordre des tables dans notre FROM clause, nous obtiendrons un résultat similaire à la jointure droite de l'exemple précédent.

SELECT 
    p.PetName,
    pt.PetType
FROM PetTypes pt
LEFT JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;

Résultat :

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Tweet     | Bird      |
| Fluffy    | Cat       |
| Scratch   | Cat       |
| Meow      | Cat       |
| Fetch     | Dog       |
| Wag       | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

Ainsi, vous pouvez voir que toute différence résultante entre les jointures gauche et droite dépend uniquement de la façon dont vous ordonnez les colonnes dans le FROM clause.

Voir SQL Left Join pour plus d'exemples, y compris une jointure gauche qui joint 3 tables.

La jointure complète

Le SQL FULL JOIN (ou FULL OUTER JOIN ) renvoie toutes les lignes, tant qu'il y a des données correspondantes dans l'une des tables.

En d'autres termes, c'est comme avoir à la fois une jointure gauche et une jointure droite dans une même jointure.

Voici un exemple de jointure complète.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;

Résultat :

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

Cela renvoie le même résultat que nous avons obtenu avec la jointure droite, mais il aurait renvoyé un résultat différent s'il y avait eu une ligne dans la table de gauche qui n'avait pas de valeur correspondante dans la table de droite.

Échangeons les noms de table et réexécutons-le.

SELECT 
    p.PetName,
    pt.PetType
FROM PetTypes pt
FULL JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;

Résultat :

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Tweet     | Bird      |
| Fluffy    | Cat       |
| Scratch   | Cat       |
| Meow      | Cat       |
| Fetch     | Dog       |
| Wag       | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

Même résultat.

Voir SQL Full Join pour plus d'exemples, y compris une jointure complète qui joint 3 tables.

La jointure croisée

Le SQL CROSS JOIN renvoie les lignes qui combinent chaque ligne de la première table avec chaque ligne de la deuxième table.

En d'autres termes, il renvoie le produit cartésien des lignes des tables de la jointure.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
CROSS JOIN PetTypes pt;

Résultat :

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Bird      |
| Fetch     | Bird      |
| Scratch   | Bird      |
| Wag       | Bird      |
| Tweet     | Bird      |
| Fluffy    | Bird      |
| Bark      | Bird      |
| Meow      | Bird      |
| Fluffy    | Cat       |
| Fetch     | Cat       |
| Scratch   | Cat       |
| Wag       | Cat       |
| Tweet     | Cat       |
| Fluffy    | Cat       |
| Bark      | Cat       |
| Meow      | Cat       |
| Fluffy    | Dog       |
| Fetch     | Dog       |
| Scratch   | Dog       |
| Wag       | Dog       |
| Tweet     | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Dog       |
| Fluffy    | Rabbit    |
| Fetch     | Rabbit    |
| Scratch   | Rabbit    |
| Wag       | Rabbit    |
| Tweet     | Rabbit    |
| Fluffy    | Rabbit    |
| Bark      | Rabbit    |
| Meow      | Rabbit    |
+-----------+-----------+
(32 rows affected)

Comme vous pouvez probablement l'imaginer, cela pourrait être très dangereux si vous l'exécutez sur les mauvaises tables.

Cela revient au même :

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p, PetTypes pt;

Vous pouvez ajouter un WHERE clause à une jointure croisée, qui la transformera en jointure interne.

Comme ceci :

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
CROSS JOIN PetTypes pt
WHERE p.PetTypeId = pt.PetTypeId;

Résultat :

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+
(8 rows affected)

Voir SQL Cross Join pour plus d'exemples.

La jointure naturelle

Le SQL NATURAL JOIN est un type d'équi-jointure où le prédicat de jointure apparaît implicitement en comparant toutes les colonnes des deux tables qui ont les mêmes noms de colonne dans les tables jointes.

Le jeu de résultats contient une seule colonne pour chaque paire de colonnes portant le même nom. Si aucune colonne portant le même nom n'est trouvée, le résultat sera une jointure croisée.

SELECT 
    Pets.PetName,
    PetTypes.PetType
FROM Pets NATURAL JOIN PetTypes;

Résultat :

petname | pettype 
---------+---------
 Fluffy  | Cat
 Fetch   | Dog
 Scratch | Cat
 Wag     | Dog
 Tweet   | Bird
 Fluffy  | Dog
 Bark    | Dog
 Meow    | Cat
(8 rows)

En fait, la jointure naturelle n'est pas réellement un type de jointure, comme le considère la norme ANSI. C'est un mot-clé que vous pouvez éventuellement insérer afin de faire de la jointure une jointure naturelle.

Par conséquent, nous pourrions remplacer l'exemple ci-dessus par NATURAL INNER JOIN si nous voulions :

SELECT 
    Pets.PetName,
    PetTypes.PetType
FROM Pets NATURAL INNER JOIN PetTypes;

Comme mentionné précédemment, les jointures internes sont le type de jointure par défaut, donc si vous omettez le type de jointure (par exemple, INNER , LEFT , RIGHT , etc.), elle est alors traitée comme une jointure interne.

Si le formatage de ces résultats semble différent des résultats précédents, c'est parce que j'ai dû passer à PostgreSQL pour exécuter cette requête. J'ai exécuté les exemples précédents dans SQL Server, mais SQL Server ne prend pas en charge la jointure naturelle.

Voir SQL Natural Join pour plus d'exemples, y compris une jointure naturelle qui joint 3 tables.

L'auto-adhésion

Le SQL SELF JOIN joint une table à elle-même.

Un exemple classique d'auto-jointure se trouve dans une table Employés. Dans un tel tableau, un employé pourrait rendre compte à un autre employé. Par conséquent, vous pouvez utiliser une auto-jointure pour joindre la table sur sa colonne d'ID d'employé et sa colonne d'ID de responsable.

Supposons que nous ayons le tableau suivant :

+--------------+-------------+------------+-------------+
| EmployeeId   | FirstName   | LastName   | ReportsTo   |
|--------------+-------------+------------+-------------|
| 1            | Homer       | Connery    | NULL        |
| 2            | Bart        | Pitt       | 1           |
| 3            | Maggie      | Griffin    | 1           |
| 4            | Peter       | Farnsworth | 2           |
| 5            | Marge       | Morrison   | NULL        |
| 6            | Lisa        | Batch      | 5           |
| 7            | Dave        | Zuckerberg | 6           |
| 8            | Vlad        | Cook       | 7           |
+--------------+-------------+------------+-------------+

Nous pouvons faire une auto-jointure sur cette table pour renvoyer tous les employés et leurs responsables.

SELECT
    CONCAT(e1.FirstName, ' ', e1.LastName) AS Employee,
    CONCAT(e2.FirstName, ' ', e2.LastName) AS Manager
FROM Employees e1
LEFT JOIN Employees e2 
ON e1.ReportsTo = e2.EmployeeId;

Résultat :

+------------------+-----------------+
| Employee         | Manager         |
|------------------+-----------------|
| Homer Connery    |                 |
| Bart Pitt        | Homer Connery   |
| Maggie Griffin   | Homer Connery   |
| Peter Farnsworth | Bart Pitt       |
| Marge Morrison   |                 |
| Lisa Batch       | Marge Morrison  |
| Dave Zuckerberg  | Lisa Batch      |
| Vlad Cook        | Dave Zuckerberg |
+------------------+-----------------+

Voir SQL Self Join pour plus d'exemples.