Un LEFT JOIN garde tous les clients de la table de gauche, sauf si un filtre placé au mauvais endroit les retire en silence. La requête tourne sans erreur, les chiffres ont l'air plausibles, et un tiers des clients a disparu.
Vous invitez tous vos clients à un événement et vous notez ce qu'ils commandent au buffet. Si vous ne gardez sur la liste que ceux qui ont commandé quelque chose, vous n'avez plus la liste des invités : vous avez la liste des consommateurs. Le piège est exactement celui-là.
Une jointure associe les lignes de deux tables sur une clé commune. Le type de jointure décide de ce qu'il advient des lignes sans correspondance.
Base jouet : des clients et leurs commandes sur l'année. La question : « tous les clients, avec leurs commandes depuis juillet ». Choisissez la requête et regardez ce qui revient. Les NULL apparaissent en gris.
| client | commande | mois | montant |
|---|
Les commandes sont tirées au hasard (1 à 3 par client ayant commandé). Le tableau montre les 7 premières lignes du résultat. La requête LEFT + WHERE donne exactement le même résultat que INNER + WHERE.
Le nombre de clients renvoyés par LEFT + WHERE est le nombre de clients qui ont une commande dans la période : rien de plus. Si la période est courte, la liste fond. La courbe suit la part de clients ayant commandé récemment, avec les réglages précédents pour le reste.
Les valeurs sont calculées en rejouant la requête sur une base de même taille, de 0 % à 85 % de clients actifs, avec la même part de clients sans aucune commande.
Voici comment écrire une jointure sans perdre de lignes en route, puis le code de la version correcte et de l'anti-jointure.
-- Tous les clients, avec leurs commandes depuis juillet (version correcte) SELECT c.id, c.nom, o.id AS commande_id, o.montant FROM clients c LEFT JOIN commandes o ON o.client_id = c.id AND o.mois >= 7; -- le filtre est dans ON -- Clients qui n'ont jamais commandé : anti-jointure SELECT c.id, c.nom FROM clients c LEFT JOIN commandes o ON o.client_id = c.id WHERE o.id IS NULL; -- Contrôle : combien de clients avant, combien après ? SELECT COUNT(*) FROM clients; SELECT COUNT(DISTINCT c.id) FROM clients c LEFT JOIN commandes o ON o.client_id = c.id AND o.mois >= 7;
On écrit SELECT en premier, la base le lit en dernier : pourquoi un alias n'existe pas dans le WHERE, et ce que cela change.
Statistiques, finance quantitative, machine learning, deep learning, LLM, agents IA, MLOps : 321 épisodes avec des simulateurs à manipuler, pas des vidéos.
Statistics, quantitative finance, machine learning, deep learning, LLMs, AI agents, MLOps: 321 interactive episodes with simulators to play with, not videos.