Les jointures
Ce que tu vas apprendre
- Pourquoi on répartit les données dans plusieurs tables, puis comment les recombiner.
- Utiliser
INNER JOINetLEFT JOIN. - Écrire des requêtes lisibles avec des alias.
Le problème
La table recettes contient seulement un categorie_id. Si tu lis cette table, tu vois des numéros, pas des noms :
| id | titre | categorie_id |
|---|---|---|
| 1 | Velouté de potimarron | 1 |
| 2 | Gratin dauphinois | 2 |
| 4 | Tarte aux pommes | 3 |
Le nom « Desserts » est dans la table categories. Une jointure (join) associe les lignes de deux tables grâce à une colonne commune.
INNER JOIN
SELECT recettes.titre, categories.nom
FROM recettes
INNER JOIN categories ON categories.id = recettes.categorie_id;
Résultat (extrait, une ligne par catégorie pour faire court) :
| titre | nom |
|---|---|
| Velouté de potimarron | Entrées |
| Gratin dauphinois | Plats |
| Tarte aux pommes | Desserts |
Après ON, tu écris la condition qui relie les lignes. PostgreSQL associe chaque recette à la catégorie dont l'id correspond.
INNER JOIN ne garde que les lignes qui ont une correspondance des deux côtés. On peut écrire JOIN tout court : c'est la même chose.
Les alias
Les noms de table répétés alourdissent la requête. Donne-leur un alias, un surnom court :
SELECT r.titre, c.nom AS categorie
FROM recettes AS r
JOIN categories AS c ON c.id = r.categorie_id
WHERE c.nom = 'Desserts'
ORDER BY r.titre;
AS categorie renomme aussi la colonne du résultat. Le WHERE et le ORDER BY s'appliquent comme avant, sur les colonnes des deux tables.
LEFT JOIN
Que se passe-t-il pour une catégorie sans recette, comme « Boissons » ? Un INNER JOIN l'oublie. Un LEFT JOIN garde toutes les lignes de la table de gauche, celle citée après FROM :
SELECT c.nom, r.titre
FROM categories AS c
LEFT JOIN recettes AS r ON r.categorie_id = c.id;
Résultat (extrait) :
| nom | titre |
|---|---|
| Entrées | Velouté de potimarron |
| Plats | Gratin dauphinois |
| Desserts | Tarte aux pommes |
| Boissons | NULL |
Quand aucune recette ne correspond, les colonnes de droite valent NULL.
Trouver ce qui n'a pas de correspondance
Cette propriété sert à repérer les lignes orphelines. Voici les catégories sans aucune recette :
SELECT c.nom
FROM categories AS c
LEFT JOIN recettes AS r ON r.categorie_id = c.id
WHERE r.id IS NULL;
On garde les lignes où le côté droit est vide. Rappelle-toi qu'un NULL se teste avec IS NULL, jamais avec =.
Quel type de jointure choisir ?
| Besoin | Jointure |
|---|---|
| Seulement les lignes liées des deux côtés | INNER JOIN |
| Toute la table de gauche, liée ou non | LEFT JOIN |
| Toute la table de droite, liée ou non | RIGHT JOIN |
RIGHT JOIN est l'image miroir de LEFT JOIN. On l'utilise rarement : il suffit d'échanger l'ordre des tables.
Joindre trois tables
Tu enchaînes les JOIN. Voici chaque ingrédient avec sa recette et sa catégorie :
SELECT r.titre, c.nom AS categorie, i.nom AS ingredient
FROM ingredients AS i
JOIN recettes AS r ON r.id = i.recette_id
JOIN categories AS c ON c.id = r.categorie_id;
Chaque JOIN ajoute une table, avec sa propre condition ON.
ON. Sans elle (avec une virgule entre les tables, ou avec CROSS JOIN), PostgreSQL associe chaque ligne de la première table à chaque ligne de la seconde. Avec 1 000 lignes de chaque côté, tu obtiens 1 000 000 de lignes.id ou nom, préfixe-la par l'alias de sa table. Sinon PostgreSQL répond que la colonne est « ambiguë ».À retenir
- Une jointure recombine des tables grâce à une colonne commune, en général une clé étrangère.
INNER JOIN ... ONgarde seulement les lignes qui se correspondent des deux côtés.LEFT JOINgarde toutes les lignes de gauche et metNULLà droite quand rien ne correspond.LEFT JOIN ... WHERE droite.id IS NULLtrouve les lignes sans correspondance.- Utilise des alias courts et préfixe les colonnes pour lever toute ambiguïté.
Pour aller plus loin
Sources officielles
Ensuite
Créer des tables
Définir ses propres tables avec CREATE TABLE, choisir les types, poser des contraintes et relier les tables par des clés étrangères.
Agrégats et index
Calculer des totaux et des moyennes avec COUNT, SUM, AVG, GROUP BY et HAVING, puis accélérer les recherches avec un index.
- Projet
- Lignes de code
- Niveau
- Cave
- Appartement
- SQL
- Pièce
- 4/7
- Plan n°
- sql/04.jointures