SQL LEFT JOIN : renvoyer des lignes avec correspondances facultatives
SQL LEFT JOIN renvoie chaque ligne de la table de gauche et y rattache les lignes correspondantes de la table de droite. En SQL, c’est une jointure externe : lorsqu’aucune correspondance n’existe, les colonnes de droite sont remplies avec NULL. Utilisez-la quand vous devez conserver tous les enregistrements d’une table, même sans données liées, par exemple pour lister tous les clients qu’ils aient passé commande ou non. LEFT JOIN et LEFT OUTER JOIN sont des mots-clés identiques ; OUTER est facultatif.
Exemple SQL LEFT JOIN pour renvoyer toutes les lignes
Sortie :
La sortie apparaîtra ici...
Sortie :
+------+-------+
| nom | total |
+------+-------+
| Alma | 79 |
| Alma | 150 |
| Ben | NULL |
| Cara | 45 |
+------+-------+
4 row(s)
Comment cet exemple fonctionne
clientscontient trois personnes ;commandescontient trois commandes liées parclient_id.LEFT JOIN commandes o ON o.client_id = c.idassocie chaque client à chaque commande qui correspond à sonid. Alma a deux commandes, donc elle produit deux lignes en sortie.- Ben n’a aucune commande. LEFT JOIN conserve sa ligne et remplit
o.totalavec NULL au lieu de l’exclure du résultat (ce que ferait INNER JOIN). ORDER BY c.id, o.idgarde la sortie groupée par client et stable à l’intérieur de chaque client. Le NULL dans la colonnetotalde Ben signale l’absence de correspondance, pas une commande à valeur zéro.
ON vs WHERE : pourquoi l’emplacement du filtre compte
Placer un filtre sur la table de droite dans WHERE au lieu de ON est l’erreur la plus fréquente avec LEFT JOIN : cela transforme silencieusement la jointure externe en jointure interne.
-- Faux : WHERE supprime Ben car son o.total est NULL
SELECT c.nom, o.total
FROM clients c
LEFT JOIN commandes o ON o.client_id = c.id
WHERE o.total > 50;
-- Correct : ON filtre pendant la correspondance, Ben reste avec des NULL
SELECT c.nom, o.total
FROM clients c
LEFT JOIN commandes o ON o.client_id = c.id AND o.total > 50;
Les conditions de ON sont évaluées pendant la jointure : les lignes de gauche sans correspondance apparaissent toujours avec des NULL. WHERE s’exécute après la jointure, donc filtre toutes les lignes où la colonne de droite est NULL, ce qui supprime précisément les lignes que LEFT JOIN doit préserver.
Anti-join : trouver les lignes sans correspondance
LEFT JOIN combiné à un test IS NULL sur une colonne de la table de droite est une méthode standard pour trouver des enregistrements liés manquants :
SELECT c.nom
FROM clients c
LEFT JOIN commandes o ON o.client_id = c.id
WHERE o.id IS NULL;
Cela renvoie uniquement Ben, le client qui n’a aucune commande. Ce motif fonctionne parce que o.id est NULL uniquement pour les lignes de gauche sans correspondance. NOT EXISTS donne le même résultat et peut être plus lisible quand aucune colonne de la table de droite n’est nécessaire dans la sortie.
LEFT JOIN vs INNER JOIN
| LEFT JOIN | INNER JOIN |
|---|---|
| Toutes les lignes de gauche, NULL pour les colonnes de droite sans correspondance | Uniquement les lignes qui correspondent des deux côtés |
| Nombre de lignes ≥ nombre de lignes de la table de gauche | Nombre de lignes ≤ nombre de lignes de la plus petite table |
| À utiliser quand les lignes sans correspondance ont du sens (rapports, contrôles de complétude) | À utiliser quand chaque ligne du résultat doit avoir des données valides des deux tables |
Règle : commencez avec LEFT JOIN quand conserver toutes les lignes de gauche est important. Passez à INNER JOIN quand les lignes sans correspondance sont non pertinentes ou invalides.
Erreurs courantes avec SQL LEFT JOIN
Multiplication des lignes dans les jointures un-à-plusieurs
LEFT JOIN produit une ligne de sortie par paire correspondante. Si un client a dix commandes, ce client apparaît dix fois. Agréger sans tenir compte de cela gonfle les totaux.
-- Faux : compte les lignes de commande, pas les clients
SELECT COUNT(*) FROM clients c
LEFT JOIN commandes o ON o.client_id = c.id;
-- Correct : compter les clients distincts
SELECT COUNT(DISTINCT c.id) FROM clients c
LEFT JOIN commandes o ON o.client_id = c.id;
Utiliser SELECT * avec des jointures
SELECT * dans une requête avec jointure renvoie des noms de colonnes en double (c.id et o.id), ce qui crée de la confusion dans le code applicatif. Listez toujours explicitement les colonnes nécessaires.
Notes de performance
Indexez la clé de jointure sur la table de droite (commandes.client_id) pour que le moteur puisse chercher les correspondances au lieu de balayer la table. Pour une grande table de droite où seule une partie des lignes est pertinente, préfiltrez avec une sous-requête ou déplacez le filtre dans la clause ON, pas dans WHERE, pour réduire le coût de jointure tout en conservant la sémantique de LEFT JOIN.
FAQ
Quelle est la différence entre LEFT JOIN et LEFT OUTER JOIN ?
Aucune. LEFT JOIN et LEFT OUTER JOIN sont des synonymes définis par le standard SQL. Toutes les bases majeures (PostgreSQL, MySQL, SQLite, SQL Server, Oracle) les traitent de manière identique. La plupart des développeurs omettent OUTER pour aller à l’essentiel.
Pourquoi mon LEFT JOIN renvoie-t-il moins de lignes après l’ajout d’une clause WHERE ?
Un filtre WHERE sur une colonne de la table de droite supprime les lignes étendues avec NULL, ce qui transforme le LEFT JOIN en INNER JOIN effectif. Déplacez la condition dans la clause ON pour conserver les lignes de gauche sans correspondance dans le résultat.
Quand utiliser LEFT JOIN au lieu de INNER JOIN ?
Utilisez LEFT JOIN quand les lignes de gauche doivent apparaître dans la sortie avec ou sans correspondance : rapports de complétude, contrôles de données manquantes et enrichissement optionnel. Utilisez INNER JOIN quand seules les lignes correspondantes sont valides et que les lignes sans correspondance doivent être exclues.