Cours

SQL Leçon 6

Relier des tables : les jointures

Répartir les données dans plusieurs tables reliées par des clés étrangères, et les rassembler avec JOIN.

25 min

À la fin de cette leçon, tu sauras

  • Comprendre pourquoi on sépare les données en plusieurs tables
  • Relier deux tables avec une clé étrangère
  • Rassembler les données avec JOIN

Pourquoi plusieurs tables ?

Imagine qu'on note dans chaque note d'élève le nom complet de la matière et du professeur. Si le professeur change, il faut modifier des centaines de lignes, avec un risque d'erreur. On préfère ranger chaque chose une seule fois dans sa propre table, et relier les tables entre elles.

 classes                    eleves
 id | nom                   id | prenom | classe_id
----+-----------            ----+--------+-----------
  1 | BTS SIO 1              1 | Léa    |         1
  2 | BTS SIO 2              2 | Tom    |         2
                             3 | Inès   |         1

La colonne classe_id de la table eleves contient l'id d'une classe : c'est une clé étrangère. Léa et Inès sont en BTS SIO 1, Tom en BTS SIO 2.

CREATE TABLE eleves (
    id INT PRIMARY KEY AUTO_INCREMENT,
    prenom VARCHAR(50) NOT NULL,
    classe_id INT,
    FOREIGN KEY (classe_id) REFERENCES classes(id)
);

La ligne FOREIGN KEY demande à la base de vérifier que chaque classe_id correspond bien à une classe qui existe.

JOIN : rassembler

SELECT eleves.prenom, classes.nom
FROM eleves
JOIN classes ON eleves.classe_id = classes.id;

Pour chaque élève, la base cherche la classe dont l'id est égal à son classe_id, et met les colonnes côte à côte. Comme les deux tables ont une colonne id, on précise table.colonne pour éviter toute ambiguïté.

INNER JOIN et LEFT JOIN

  • JOIN (ou INNER JOIN) garde seulement les élèves qui ont une classe ;
  • LEFT JOIN garde tous les élèves de la table de gauche, même sans classe (les colonnes de la classe sont alors vides, NULL).

Astuce : on peut donner un surnom court aux tables : FROM eleves e JOIN classes c ON e.classe_id = c.id.

À toi de jouer

Avec les tables eleves et classes ci-dessus, écris une requête qui affiche le prénom de chaque élève et le nom de sa classe, en utilisant un JOIN sur eleves.classe_id = classes.id.

requete.sql
Résultat

Écris une requête : elle s'exécute pendant que tu tapes, sur une base d'exemple qui repart de zéro à chaque fois.

Voir les tables de la base d'exemple

classes (3 lignes)

idnom
1BTS SIO 1
2BTS SIO 2
3Terminale STMG

eleves (7 lignes)

idprenomnomagevilleclasse_id
1LéaMartin18Chartres1
2TomBernard19Dreux2
3InèsPetit18Chartres1
4HugoDurand20Paris2
5ChloéLambert17Lucé3
6NathanDubois19Chartres1
7SarahMoreau18DreuxNULL

notes (9 lignes)

ideleve_idmatierenote
11Développement16
21Réseau12
32Développement11
42Réseau15
53Développement18
64Réseau9
76Développement13
86Réseau14
95Gestion15
  • Le résultat associe chaque élève à sa classe
  • La requête sélectionne le prénom et le nom de la classe
  • Elle part de la table eleves
  • Elle fait un JOIN avec classes
  • La condition relie classe_id à id
Bloqué ? Voir une solution
SELECT eleves.prenom, classes.nom
FROM eleves
JOIN classes ON eleves.classe_id = classes.id;

Quiz

1Qu'est-ce qu'une clé étrangère ?
2Un élève n'a pas de classe. Quelle jointure le garde dans le résultat ?
3Pourquoi écrire eleves.id plutôt que id dans une jointure ?