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.
À 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 | 1La 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(ouINNER JOIN) garde seulement les élèves qui ont une classe ;LEFT JOINgarde 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.
É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)
| id | nom |
|---|---|
| 1 | BTS SIO 1 |
| 2 | BTS SIO 2 |
| 3 | Terminale STMG |
eleves (7 lignes)
| id | prenom | nom | age | ville | classe_id |
|---|---|---|---|---|---|
| 1 | Léa | Martin | 18 | Chartres | 1 |
| 2 | Tom | Bernard | 19 | Dreux | 2 |
| 3 | Inès | Petit | 18 | Chartres | 1 |
| 4 | Hugo | Durand | 20 | Paris | 2 |
| 5 | Chloé | Lambert | 17 | Lucé | 3 |
| 6 | Nathan | Dubois | 19 | Chartres | 1 |
| 7 | Sarah | Moreau | 18 | Dreux | NULL |
notes (9 lignes)
| id | eleve_id | matiere | note |
|---|---|---|---|
| 1 | 1 | Développement | 16 |
| 2 | 1 | Réseau | 12 |
| 3 | 2 | Développement | 11 |
| 4 | 2 | Réseau | 15 |
| 5 | 3 | Développement | 18 |
| 6 | 4 | Réseau | 9 |
| 7 | 6 | Développement | 13 |
| 8 | 6 | Réseau | 14 |
| 9 | 5 | Gestion | 15 |
- 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
Bravo, toutes les consignes sont réussies !
Bloqué ? Voir une solution
SELECT eleves.prenom, classes.nom
FROM eleves
JOIN classes ON eleves.classe_id = classes.id;