Une jointure SQL associe les enregistrements de deux tables ou plus au sein d’une même requête, en s’appuyant sur une colonne de liaison partagée. Cette opération est au cœur de la conception relationnelle et permet d’exploiter pleinement la structure normalisée d’une base de données.
Table des matières
Quels sont les différents types de jointure en SQL ?
SQL propose quatre opérateurs de liaison principaux, chacun délimitant un périmètre différent dans l’ensemble des lignes retournées. Le choix dépend de la présence ou non de correspondances attendues entre les deux tables interrogées.
| Opérateur | Lignes retournées |
|---|---|
INNER JOIN | Uniquement les paires dont la condition de liaison est vérifiée dans les deux tables |
LEFT JOIN | Toutes les lignes de la table de gauche, NULL si aucune correspondance à droite |
RIGHT JOIN | Toutes les lignes de la table de droite, NULL si aucune correspondance à gauche |
FULL OUTER JOIN | L’intégralité des lignes des deux tables, NULL de part et d’autre si absence de correspondance |
INNER JOIN est l’opérateur le plus courant : il ne retient que les enregistrements ayant une correspondance dans les deux tables simultanément. LEFT JOIN et RIGHT JOIN incluent en plus les lignes sans équivalent du côté dominant, en affichant NULL pour les colonnes manquantes. FULL OUTER JOIN couvre quant à lui la totalité des enregistrements des deux tables, supporté nativement par PostgreSQL et SQL Server, mais à simuler sur MySQL via UNION.
Quel est le but des jointures SQL ?
Les bases relationnelles fragmentent volontairement les données en plusieurs tables pour éliminer la redondance et garantir la cohérence des informations. Une table clients centralise les coordonnées, pendant qu’une table commandes enregistre chaque achat effectué. Ces deux entités partagent une colonne de liaison — typiquement une clé primaire côté clients et une clé étrangère côté commandes.
Récupérer simultanément le nom d’un client et ses achats associés sans jointure obligerait à multiplier les requêtes et à assembler manuellement les résultats côté applicatif. Une seule instruction avec JOIN accomplit ce travail directement au niveau du moteur SQL, ce qui allège la charge réseau et le code métier. Cette centralisation du traitement est l’un des avantages majeurs des systèmes de gestion relationnels.
Le principe repose sur la non-duplication : le nom du client ne figure qu’une seule fois dans clients, quelle que soit la quantité de commandes enregistrées. La jointure retrouve ce nom à la volée lors de l’exécution de la requête, sans jamais stocker de copie dans commandes. C’est ce mécanisme qui garantit l’intégrité référentielle des données à long terme.
Les deux tables de référence utilisées dans les exemples suivants illustrent ce modèle classique :
-- Table des clients enregistrés
CREATE TABLE clients (
id INT PRIMARY KEY,
nom VARCHAR(100),
ville VARCHAR(100)
);
-- Table des achats liés à chaque client
CREATE TABLE commandes (
id INT PRIMARY KEY,
client_id INT, -- référence vers clients.id
produit VARCHAR(100),
montant DECIMAL(10,2)
);
La colonne client_id dans commandes pointe vers id dans clients et représente le point d’ancrage de toutes les jointures de cet article. Toute valeur orpheline dans cette colonne — sans correspondance dans clients — sera traitée différemment selon le type de jointure choisi. Il faut donc s’assurer que cette relation est correctement définie avant d’interroger les deux tables ensemble.
Comment fonctionne une jointure ?
Lors de l’exécution, le moteur relationnel évalue la condition de la clause ON en comparant les valeurs de la colonne de liaison ligne par ligne entre les deux tables impliquées. Seules les paires satisfaisant cette condition sont transmises à l’étape suivante du plan d’exécution. Ce mécanisme repose presque exclusivement sur une égalité entre clé primaire et clé étrangère.
La clause ON est indissociable de tout opérateur JOIN : son absence provoque un produit cartésien, c’est-à-dire la combinaison de chaque ligne de la première table avec chaque ligne de la seconde. Avec 500 clients et 5 000 commandes, ce scénario génère 2,5 millions de lignes parasites sans valeur informative. Définir systématiquement une condition de liaison explicite est donc une règle non négociable.
Dès que plusieurs tables partagent des noms de colonnes identiques, le moteur exige une désambiguïsation par préfixage. Les alias de table allègent cette syntaxe et rendent la requête plus lisible, surtout lorsque trois tables ou plus sont assemblées dans la même instruction.
La requête ci-dessous assemble trois entités distinctes pour produire un rapport détaillé des achats :
-- Assembler clients, commandes et produits en un seul jeu de résultats
SELECT c.nom AS acheteur, cmd.date_achat, p.libelle AS article, cmd.montant
FROM commandes AS cmd
INNER JOIN clients AS c ON cmd.client_id = c.id
INNER JOIN produits AS p ON cmd.produit_id = p.id
WHERE cmd.montant > 100
ORDER BY cmd.montant DESC;
Les alias cmd, c et p remplacent les noms complets et évitent toute ambiguïté sur les colonnes partagées entre les trois tables. Le filtre WHERE s’applique après la résolution des liaisons et réduit le volume des résultats aux achats significatifs. Des index sur client_id et produit_id sont indispensables pour maintenir des performances acceptables sur des volumes élevés de données.
L’erreur la plus fréquente reste l’omission de la clause ON, souvent héritée de l’ancienne syntaxe implicite avec virgule entre les tables :
-- ❌ Incorrect : syntaxe implicite sans condition de liaison
SELECT clients.nom, commandes.produit
FROM clients, commandes;
-- ✅ Correct : opérateur JOIN avec condition ON explicite
SELECT clients.nom, commandes.produit
FROM commandes
INNER JOIN clients ON commandes.client_id = clients.id;
La syntaxe implicite était courante avant SQL-92 mais elle est aujourd’hui déconseillée par l’ensemble des éditeurs de SGBD. Elle masque l’intention du développeur et rend la requête difficile à maintenir sur des schémas complexes. Privilégier systématiquement la syntaxe JOIN ... ON garantit une lisibilité et une fiabilité à long terme du code SQL.