INNER JOIN, la jointure de base

La leçon précédente t'a montré le lien entre tables. INNER JOIN t'apprend maintenant à l'exploiter : assembler les colonnes de deux tables en un seul résultat, en suivant la relation clé étrangère → clé primaire.

Quand un numéro ne suffit pas

Certaines colonnes stockent un identifiant numérique à la place d'une valeur lisible. C'est le cas de realisateur_id dans cette table films : le numéro 1 signifie Christopher Nolan, mais rien dans la table ne te le dit directement.

Table films (extrait, fictif) — avec realisateur_id

titreanneerealisateur_id
Inception20101
Le Parrain19722
Pulp Fiction19943
Amélie Poulain20014

Pour afficher « Christopher Nolan » à côté d'Inception, il faut aller chercher l'information dans une deuxième table — realisateurs — qui fait correspondre les identifiants à leurs noms. C'est ce que fait INNER JOIN : lire dans les deux tables simultanément et assembler leurs colonnes dans un seul résultat.

La condition ON : le cœur du JOIN

La syntaxe d'INNER JOIN suit toujours le même schéma : FROM table1 INNER JOIN table2 ON condition. La condition dit comment les deux tables se correspondent — ici, l'identifiant du réalisateur dans films doit être égal à l'identifiant dans realisateurs.

Pour chaque ligne de films, PostgreSQL cherche dans realisateurs la ligne dont l'id correspond au realisateur_id du film. Les colonnes des deux lignes sont fusionnées en une seule ligne de résultat.

Table realisateurs (fictive — illustre le concept)

idnomnationalite
1Christopher NolanBritannique
2Francis Ford CoppolaAméricain
3Quentin TarantinoAméricain
4Jean-Pierre JeunetFrançais
5Fritz LangAllemand
La requête
SELECT films.titre, realisateurs.nom AS realisateur FROM films INNER JOIN realisateurs ON films.realisateur_id = realisateurs.id
Résultat — 4 films avec leur réalisateur · 4 lignes
titrerealisateur
InceptionChristopher Nolan
Le ParrainFrancis Ford Coppola
Pulp FictionQuentin Tarantino
Amélie PoulainJean-Pierre Jeunet

4 lignes — un film par ligne, chacun avec le nom de son réalisateur. Fritz Lang (id 5 dans realisateurs) est absent : il n'a aucun film dans notre table films. INNER JOIN ne garde que les lignes qui trouvent une correspondance des deux côtés. Sans la clause ON, PostgreSQL renvoie une erreur de syntaxe — ON est obligatoire.

Préfixer : de quelle table vient cette colonne ?

Les deux tables ont toutes les deux une colonne qui s'appelle id. Si tu écris SELECT id, titre FROM films INNER JOIN realisateurs ON ..., PostgreSQL ne sait pas de laquelle tu parles et renvoie une erreur : column reference "id" is ambiguous.

Le préfixe résout l'ambiguïté : films.id désigne l'identifiant du film, et realisateurs.id celui du réalisateur. La requête de la section précédente applique déjà ce principe en écrivant films.titre et realisateurs.nom.

Même quand les noms de colonnes diffèrent — titre dans films, nom dans realisateurs — on garde les préfixes par convention. Ça rend immédiatement clair de quelle table vient chaque colonne, surtout dans une requête qui joint plusieurs tables.

Les alias de table : écrire moins, lire plus

Écrire films. et realisateurs. à chaque colonne et dans la condition ON alourdit rapidement la requête. La solution : déclarer un alias pour chaque table, juste après son nom dans le FROM.

FROM films f déclare que, pour toute la requête, f désigne films. On peut alors écrire f.titre, f.realisateur_id… au lieu de films.titre, films.realisateur_id. Ce style à une ou deux lettres est la convention universelle dans les bases professionnelles.

La requête
SELECT f.titre, r.nom AS realisateur FROM films f INNER JOIN realisateurs r ON f.realisateur_id = r.id
Résultat — 4 films avec leur réalisateur (même résultat) · 4 lignes
titrerealisateur
InceptionChristopher Nolan
Le ParrainFrancis Ford Coppola
Pulp FictionQuentin Tarantino
Amélie PoulainJean-Pierre Jeunet

Le résultat est identique — seul le style de la requête change. f = films, r = realisateurs.

JOIN + WHERE + ORDER BY

Une fois les deux tables jointes, tous les outils des parcours précédents s'appliquent normalement au résultat combiné. WHERE filtre les lignes, ORDER BY les trie — exactement comme sur une table simple.

Tu peux filtrer ou trier sur une colonne de n'importe quelle table jointe. Ici, WHERE r.nationalite = 'Américain' filtre sur un champ de realisateurs, alors que le résultat affiche aussi des colonnes de films.

La requête
SELECT f.titre, r.nom AS realisateur, r.nationalite FROM films f INNER JOIN realisateurs r ON f.realisateur_id = r.id WHERE r.nationalite = 'Américain' ORDER BY f.annee
Les films de réalisateurs américains dans notre sélection · 2 lignes
titrerealisateurnationalite
Le ParrainFrancis Ford CoppolaAméricain
Pulp FictionQuentin TarantinoAméricain

WHERE et ORDER BY peuvent porter sur n'importe quelle colonne de n'importe quelle table jointe — pas seulement sur la table principale du FROM.

Récapitulatif

Ce que tu retiens de cette leçon :

📌 INNER JOIN — l'essentiel
INNER JOIN ... ON→ relier deux tables via leur lien clé étrangère = clé primaire
table.colonne→ éviter l'ambiguïté quand deux tables partagent un nom de colonne (ex. id)
AS realisateur→ nommer clairement une colonne préfixée dans le résultat
FROM films f→ alias de table : f = raccourci de films dans toute la requête
WHERE / ORDER BY→ filtrer et trier s'appliquent normalement au résultat joint
Exemple complet
SELECT f.titre, r.nom AS realisateur
FROM films f INNER JOIN realisateurs r ON f.realisateur_id = r.id

💡 Bon à savoir : INNER JOIN ne garde que les lignes qui ont une correspondance dans les deux tables. Fritz Lang — présent dans realisateurs mais sans film dans films — n'apparaît pas. C'est précisément ce que LEFT JOIN corrige : il affiche aussi les lignes sans correspondance. Ça arrive dans la leçon suivante.

Passe à la pratique

Cette leçon t'a montré la théorie. Pour maîtriser SQL, rien ne vaut la pratique : accède aux exercices et au bac à sable PostgreSQL réel.

← Tous les cours SQL