Les jointures entre tables

Objectifs et prérequis

Prérequis : requêtes de sélection SQL , le modèle relationnel (clé étrangère)

À l’issue de ce chapitre, vous saurez :

  • expliquer pourquoi une jointure est nécessaire pour croiser des données de plusieurs tables ;
  • écrire une jointure SQL avec la syntaxe JOIN ... ON ;
  • écrire une jointure SQL avec la syntaxe WHERE (produit cartésien filtré) ;
  • réaliser une jointure sur trois tables.

Pourquoi les jointures ?

Le modèle relationnel répartit les données dans plusieurs tables pour éviter la redondance. Mais quand on souhaite combiner des informations provenant de tables différentes, il faut les relier : c’est le rôle de la jointure.

Tables d’exemple

On considère une base de données de gestion scolaire avec trois tables :

Eleves :

id_elevenomprenomid_classe
1DupontMarie101
2MartinLucas102
3LeroyEmma101
4PetitHugo102

Classes :

id_classenom_classesalle
101Terminale AB204
102Terminale BC112

Matieres :

id_matierenom_matiere#id_classeenseignant
1NSI101M. Dupuis
2Mathématiques101Mme Roche
3NSI102M. Dupuis
4Physique102M. Laurent

L’attribut id_classe dans Eleves est une clé étrangère qui référence Classes.id_classe. C’est cet attribut commun qui permet de relier les deux tables.

Comprendre la jointure pas à pas

On souhaite afficher, pour chaque élève, son nom et le nom de sa classe.

Étape 1 : identifier l’attribut commun. L’attribut id_classe est présent dans les deux tables : c’est la clé étrangère dans Eleves et la clé primaire dans Classes.

Étape 2 : faire correspondre les lignes. Pour Marie Dupont, id_classe = 101. Dans Classes, la ligne 101 correspond à « Terminale A ». On associe donc Marie à « Terminale A ».

Étape 3 : construire le résultat.

nomprenomnom_classesalle
DupontMarieTerminale AB204
MartinLucasTerminale BC112
LeroyEmmaTerminale AB204
PetitHugoTerminale BC112

Syntaxe SQL : JOIN … ON

C’est la syntaxe recommandée. Elle exprime clairement quelle table on rejoint et sur quelle condition.

SELECT Eleves.nom, Eleves.prenom, Classes.nom_classe
FROM Eleves
JOIN Classes ON Eleves.id_classe = Classes.id_classe;

La clause JOIN Classes indique qu’on combine la table Eleves avec Classes. La condition ON Eleves.id_classe = Classes.id_classe précise qu’on relie les lignes dont la valeur de id_classe est identique.

On peut ajouter un filtre avec WHERE :

SELECT Eleves.nom, Eleves.prenom
FROM Eleves
JOIN Classes ON Eleves.id_classe = Classes.id_classe
WHERE Classes.salle = 'B204';

Résultat : Dupont Marie, Leroy Emma (les élèves de la salle B204).

Syntaxe SQL : WHERE (produit cartésien filtré)

Une autre syntaxe, plus ancienne, consiste à lister les tables dans FROM et à exprimer la condition de jointure dans WHERE :

SELECT Eleves.nom, Eleves.prenom, Classes.nom_classe
FROM Eleves, Classes
WHERE Eleves.id_classe = Classes.id_classe;

Le résultat est identique. Sans la condition WHERE, le SGBD calculerait le produit cartésien (toutes les combinaisons possibles de lignes des deux tables, soit $4 \times 2 = 8$ lignes), ce qui ne ferait pas sens.

Les deux syntaxes sont équivalentes, mais JOIN ... ON est préférable car elle sépare clairement la condition de jointure des filtres (WHERE).

Jointure sur trois tables

Pour combiner trois tables, on enchaîne les clauses JOIN.

Afficher le nom de chaque élève et les matières enseignées dans sa classe :

SELECT Eleves.nom, Eleves.prenom, Matieres.nom_matiere, Matieres.enseignant
FROM Eleves
JOIN Classes ON Eleves.id_classe = Classes.id_classe
JOIN Matieres ON Classes.id_classe = Matieres.id_classe;

Résultat :

nomprenomnom_matiereenseignant
DupontMarieNSIM. Dupuis
DupontMarieMathématiquesMme Roche
LeroyEmmaNSIM. Dupuis
LeroyEmmaMathématiquesMme Roche
MartinLucasNSIM. Dupuis
MartinLucasPhysiqueM. Laurent
PetitHugoNSIM. Dupuis
PetitHugoPhysiqueM. Laurent

On peut bien sûr filtrer : quels élèves ont M. Dupuis comme enseignant ?

SELECT Eleves.nom, Eleves.prenom
FROM Eleves
JOIN Classes ON Eleves.id_classe = Classes.id_classe
JOIN Matieres ON Classes.id_classe = Matieres.id_classe
WHERE Matieres.enseignant = 'M. Dupuis';

Résultat : tous les élèves des deux classes (car M. Dupuis enseigne la NSI dans les deux classes).

Compter avec une jointure

Les fonctions d’agrégation fonctionnent aussi avec les jointures.

Combien d’élèves sont en Terminale A ?

SELECT COUNT(*)
FROM Eleves
JOIN Classes ON Eleves.id_classe = Classes.id_classe
WHERE Classes.nom_classe = 'Terminale A';

Résultat : 2 (Dupont Marie et Leroy Emma).

Vérifiez votre compréhension
  1. Pourquoi a-t-on besoin d’une jointure pour afficher le nom d’un élève et le nom de sa classe ?
    RéponseParce que le nom de l'élève est dans la table Eleves et le nom de la classe est dans la table Classes. Pour combiner ces informations, il faut relier les deux tables via leur attribut commun id_classe. C'est exactement le rôle d'une jointure.
  2. Que se passe-t-il si on oublie la condition de jointure (ON ou WHERE) ?
    RéponseLe SGBD calcule le produit cartésien : il combine chaque ligne de la première table avec chaque ligne de la seconde. Si la première a 4 lignes et la seconde 2, on obtient $4 \times 2 = 8$ lignes, dont la plupart n'ont pas de sens (par exemple, associer Marie à la Terminale B alors qu'elle est en Terminale A).
  3. Dans la requête SELECT E.nom FROM Eleves E JOIN Classes C ON E.id_classe = C.id_classe, que signifient E et C ?
    RéponseCe sont des alias : E remplace Eleves et C remplace Classes. Cela permet d'écrire des requêtes plus courtes et plus lisibles, surtout quand les noms de tables sont longs ou quand on joint plusieurs tables.
L'essentiel à retenir
  • Une jointure combine les lignes de deux (ou plusieurs) tables en se basant sur un attribut commun, typiquement une clé étrangère.
  • La syntaxe recommandée est JOIN ... ON : SELECT ... FROM Table1 JOIN Table2 ON Table1.clé = Table2.clé.
  • La syntaxe FROM Table1, Table2 WHERE Table1.clé = Table2.clé est équivalente mais moins explicite.
  • Sans condition de jointure, on obtient le produit cartésien (toutes les combinaisons), ce qui n’a généralement pas de sens.
  • On peut enchaîner plusieurs JOIN pour relier trois tables ou plus.
  • Les fonctions d’agrégation (COUNT, AVG, etc.) fonctionnent aussi avec les jointures.