Retour à la liste des articles Articles
11 minutes de lecture

Un guide illustré des jointures multiples

Jusqu'à présent, nos articles de la série "Un guide illustré" ont expliqué plusieurs types de jointures : INNER JOINs, OUTER JOINs (LEFT JOIN, RIGHT JOIN, FULL JOIN), CROSS JOIN, auto-joint et jointure non-équi. Dans ce dernier article de la série, nous vous montrons comment créer des requêtes SQL qui font correspondre les données de plusieurs tables en utilisant un ou plusieurs types de jointure.

Types de jointures dans les requêtes SQL

Avant d'aborder les exemples de requêtes SQL qui utilisent des types de jointures multiples, récapitulons brièvement les types de jointures que nous avons abordés jusqu'à présent, afin de nous assurer que vous comprenez bien les différences. À cette fin, voici un bref résumé sous forme de tableau. Jetez-y un coup d'œil :

Type of JOIN Matching records from tables Explanation
INNER JOIN(JOIN)

SELECT  t.id, t.size,
t.color_id, c.id, c.color
FROM tshirt t
JOIN color c  
ON t.color_id = c.id ;

Result:

id size color_id id color
2 M 1 1 yellow
3 NULL 3 3 blue
An INNER JOIN returns records that match in both tables.
LEFT JOIN

SELECT  t.id, t.size,
t.color_id, c.id, c.color
FROM tshirt t
LEFT JOIN color c  
ON t.color_id = c.id ;

Result:

id size color_id id color
2 M 1 1 yellow
3 NULL 3 3 blue
1 S NULL NULL NULL
A LEFT JOIN returns all records from the left table, even when they do not match in the right table. Missing values become NULLs.
RIGHT JOIN

SELECT  t.id, t.size,
t.color_id, c.id, c.color
FROM tshirt t
RIGHT JOIN color c  
ON t.color_id = c.id ;

Result:

id size color_id id color
2 M 1 1 yellow
3 NULL 3 3 blue
NULL NULL NULL 2 NULL
A RIGHT JOIN returns all records from the right table, even when they do not match those in the left table. Missing values become NULLs.
FULL JOIN

SELECT  t.id, t.size,
t.color_id, c.id, c.color
FROM tshirt t
FULL JOIN color c  
ON t.color_id = c.id ;
sql multiple joins

Result:

id size color_id id color
2 M 1 1 yellow
3 NULL 3 3 blue
1 S NULL NULL NULL
NULL NULL NULL 2 NULL
A FULL JOIN returns all records from both tables: left and right, even when rows do not match. Missing values become NULLs.
CROSS JOIN

SELECT  t.id, t.size,
t.color_id, c.id, c.color
FROM tshirt t
CROSS JOIN color c  ;
multiple joins sql Result:

id size color_id id color
2 M 1 1 yellow
2 M 1 2 NULL
2 M 1 3 blue
3 NULL 3 1 yellow
3 NULL 3 2 NULL
3 NULL 3 3 blue
1 S NULL 1 yellow
1 S NULL 2 NULL
1 S NULL 3 blue
A CROSS JOIN returns the Cartesian product of the records from both tables. This means that each record from the left table is joined with each record from the right table. Missing values become NULLs.

Notez que le résultat de chaque type de jointure contient des données provenant des tables tshirt et color. Le type de jointure spécifique détermine le contenu de la table à renvoyer.

Qu'est-ce qu'une jointure multiple en SQL ?

Chaque requête peut comprendre zéro, une ou plusieurs jointures. Une jointure multiple est l'utilisation de plus d'une jointure dans une seule requête. Les jointures utilisées peuvent être toutes du même type, ou leurs types peuvent être différents. Nous allons commencer notre discussion en montrant un exemple de requête qui utilise deux jointures du même type. Regardez la requête ci-dessous.

SELECT v.name, c.name,  p.lastname
FROM vehicle v
INNER JOIN color c ON  v.color_id = c.id
INNER JOIN person p ON v.person_id = p.id ;

La requête invoque deux INNER JOINs afin de joindre trois tables : vehicle, person et color. Seuls les enregistrements qui ont une correspondance dans chaque table seront renvoyés. Tout d'abord, regardons les ensembles de données qui ont été joints.

Il y a trois ensembles de données qui correspondent à trois tables dans la base de données : vehicle, color et personreprésentés ci-dessous.

person

id lastname
1 Watson
2 Miller
3 Smith
4 Brown

color

id name
1 green
2 yellow
3 blue

vehicle

id name color_id person_id
1 car 1 4
2 bicycle 2 NULL
3 motorcycle NULL 1
4 scooter 1 3

Vous pouvez voir que chaque vehicle dans la table des véhicules a une couleur, sauf pour motorcycle. Un propriétaire est attribué à chaque véhicule, à l'exception de bicycle, qui n'a pas de propriétaire. L'une des couleurs (blue) du tableau n'est attribuée à aucun véhicule. color n'est attribuée à aucun véhicule. De plus, la moto n'a pas de couleur disponible dans la base de données. D'autre part, bicycle a une couleur assignée, mais pas de propriétaire. Enfin, aucun véhicule n'est attribué à la personne nommée Miller.

Dans la requête ci-dessus, nous avons utilisé la jointure multiple pour récupérer uniquement les véhicules auxquels sont attribués une couleur et un propriétaire. La table vehicle contient la colonne color_id qui identifie la colonne color dans la table des couleurs, ainsi que la colonne person_id qui identifie le person dans la table des personnes.

Résultat de la requête :

name name lastname
car green Brown
scooter green Smith

Il s'avère que seuls deux enregistrements correspondent aux critères définis par les deux jointures internes.

L'image ci-dessous présente la séquence dans laquelle les enregistrements des tables respectives ont été joints.

Notez que toutes les opérations de JOIN sont effectuées de gauche à droite. Dans la première étape, les tables de la première JOIN sont mises en correspondance (tables vehicle et color). En conséquence, une table intermédiaire est créée. À l'étape 2, cette table intermédiaire (considérée comme la table de gauche) est jointe à une autre table (table person) en utilisant le deuxième site JOIN.

N'oubliez pas qu'une seule JOIN, quel que soit son type, produit une seule table intermédiaire (communément appelée table dérivée) lors d'une requête multi-jointures.

Jointure mixte gauche et droite avec jointure interne

Il est également possible de combiner différents types de jointures dans une requête multi-jointures. Prenons un exemple avec une INNER JOIN et une LEFT JOIN. Supposons que nous voulions interroger notre base de données sur toutes les personnes qui possèdent un véhicule de couleur ou qui ne possèdent pas de véhicule du tout.

Intuitivement, nous commencerions par la table person et la joindre à la table vehicle table à l'aide d'un LEFT JOIN. Dans ce cas, le LEFT JOIN fait correspondre chaque enregistrement de la table à un enregistrement de la table. person avec un enregistrement de la table vehicle et pour toute personne pour laquelle aucun enregistrement correspondant n'a été trouvé, les valeurs manquantes seraient complétées par NULLs. Cette jointure produira une liste de toutes les personnes de la base de données auxquelles sont associées des données sur les véhicules, même si elles n'en possèdent pas. Mais ce qui nous intéresse, c'est de voir uniquement les véhicules auxquels des couleurs ont été attribuées. Cela signifie que nous devons utiliser une INNER JOIN sur les tables vehicle et color. Voici une requête qui répond à cette exigence particulière, mais fait-elle l'affaire ?

SELECT v.name vehicle_name, c.name color_name,  p.lastname
FROM person p
LEFT JOIN vehicle v ON  v.person_id = p.id
INNER JOIN color c ON v.color_id = c.id ;

Non ! Cette requête renvoie le même résultat que celui obtenu avec notre requête précédente (qui n'utilisait que des INNER JOINs). Notre liste n'inclut pas les personnes sans véhicule.

Résultat :

vehicle_name color_name lastname
car green Brown
scooter green Smith

Mais que s'est-il passé ? Le site INNER JOIN a ignoré les résultats qui ne correspondaient pas dans les deux tables, c'est-à-dire dans la table dérivée (créée en joignant les tables person et vehicle) et la table color . Comment pouvons-nous résoudre ce problème ?

La requête suivante présente l'une des quelques solutions possibles. Ici, le tableau dérivé renvoie uniquement les véhicules avec des couleurs, et est ensuite RIGHT JOINed avec le tableau person afin d'obtenir toutes les personnes.

SELECT p.lastname, v.name, c.name
FROM vehicle v
INNER JOIN color c ON  v.color_id = c.id
RIGHT JOIN person p ON v.person_id = p.id ;

Résultat :

lastname name name
Smith scooter green
Brown car green
Miller
Watson

Nous avons maintenant une liste de toutes les personnes : celles avec des véhicules de couleur et celles sans véhicule. Nous avons commencé avec une INNER JOIN des tables vehicle et color. Chaque véhicule inclus dans la table dérivée doit avoir une couleur attribuée, c'est pourquoi ce type de jointure est approprié. Après avoir sélectionné les véhicules de couleur, nous pouvons maintenant utiliser une RIGHT JOIN sur la table dérivée avec la table person c'est ainsi que nous avons obtenu les personnes qui n'étaient pas propriétaires de véhicules à côté de celles (de la table dérivée) qui possédaient un véhicule de couleur.

Une autre méthode pour résoudre ce problème consiste à utiliser une LEFT JOIN sur la table des personnes et une sous-requête dans laquelle nous avons utilisé une INNER JOIN sur les tables vehicle et color.

Jetez un coup d'œil à la requête ci-dessous.

SELECT p.lastname, o.vehicle_name, o.color_name
FROM person p LEFT JOIN
(  SELECT v.name vehicle_name, c.name color_name, v.person_id
    FROM vehicle v
    INNER JOIN color c ON v.color_id=c.id
) o ON  o.person_id = p.id;

JOINs mixtes avec Full JOIN

Un autre type de jointure multiple utilise les jointures complètes. Tout d'abord, jetons un coup d'oeil à une jointure multiple avec des jointures complètes uniquement.

SELECT p.lastname, v.name, c.name
FROM vehicle v
FULL JOIN color c ON  v.color_id = c.id
FULL JOIN person p ON v.person_id = p.id ;

La requête ci-dessus fait correspondre les enregistrements de trois tables : person, vehicle et color de manière à ce que même les enregistrements sans correspondance dans les deux autres tables apparaissent dans le tableau de résultats. Les colonnes vides seront remplies avec les valeurs de NULL. C'est pourquoi la requête renvoie toutes les personnes, qu'elles aient ou non un véhicule, tous les véhicules, qu'une couleur leur soit ou non attribuée, et toutes les couleurs, qu'elles soient ou non attribuées à un véhicule.

Résultat :

lastname name name
Smith scooter green
Brown car green
bicycle yellow
blue
Watson motorcycle
Miller

Nous avons utilisé des jointures complètes pour joindre tous les enregistrements, même ceux qui ne correspondent pas. Rappelez-vous que les jointures complètes renvoient tous les enregistrements, tandis que les jointures internes ne renvoient que ceux qui correspondent.

L'image ci-dessous explique l'ordre dans lequel les tables ont été jointes.

FULL JOIN peut également apparaître dans une requête avec un autre type de jointure, créant ainsi une jointure multiple avec des types mixtes. La requête ci-dessous utilise une FULL JOIN avec une INNER JOIN.

SELECT p.lastname, v.name, c.name
FROM vehicle v
INNER  JOIN color c ON  v.color_id = c.id
FULL  JOIN person p ON v.person_id = p.id ;

Cette requête nous permet de récupérer une liste de toutes les personnes, qu'elles soient ou non propriétaires de véhicules, et de tous les véhicules auxquels une couleur a été attribuée.

Voici comment fonctionnent les deux jointures :

Tout d'abord, les tables vehicle et color sont combinées à l'aide d'une INNER JOIN. Ensuite, la table dérivée est combinée avec la table person à l'aide de FULL JOIN. Voici le résultat :

lastname name name
Smith scooter green
Brown car green
bicycle yellow
Watson
Miller

Résumé

Une seule requête SQL peut joindre deux tables ou plus. Lorsque trois tables ou plus sont concernées, les requêtes peuvent utiliser un seul type de jointure plusieurs fois ou plusieurs types de jointure. Lors de l'utilisation de plusieurs types de jointure, nous devons soigneusement considérer la séquence de jointure afin de produire le résultat souhaité. Les exemples présentés dans cet article montrent clairement comment un changement mineur dans le type de jointure (ou, dans le cas de jointures multiples, dans l'ordre dans lequel elles apparaissent dans la requête) peut complètement changer le résultat de la requête, faisant ou défaisant le succès de la requête.

À quelles combinaisons de jointures devons-nous prêter une attention particulière ? INNER JOINs avec OUTER JOINs, et OUTER JOINs avec OUTER JOINs. Chacune de ces combinaisons peut produire des résultats de requête erronés lorsqu'elle est utilisée de manière inappropriée.

En savoir plus sur SQL

Une connaissance de base des jointures SQL est absolument indispensable, mais la plupart des débutants en SQL se sentent intimidés par les instructions JOIN. En réalité, il n'y a absolument rien à craindre !

Dans cet article, nous avons vu comment utiliser des jointures multiples dans une seule requête : soit LIKE, soit des types mixtes JOIN. Vous trouverez de plus amples informations sur les jointures dans le matériel SQL complet de la Vertabelo Academy. Dans les cours, vous augmenterez considérablement votre expertise, en testant et en affinant vos nouvelles compétences grâce aux exercices pratiques interactifs fournis. Commencez par le cours SQL pour les débutants si vous n'avez aucune connaissance préalable de SQL. Lancez-vous dans le cours SQL JOINs pour acquérir une expérience pratique de l'interrogation de plusieurs tables grâce à des tonnes d'exercices interactifs sur les instructions JOIN. Essayez-le maintenant gratuitement !