0Pricing
Coding Interview Prep · Leçon

Multiplication des lignes lors d’une jointure

Pourquoi une jointure peut renvoyer plus de lignes que l’une ou l’autre table et comment les recruteurs le vérifient

Multiplication des lignes lors d’une jointure est une leçon Coding Interview Prep gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Coding Interview Prep, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Coding Interview Prep comprend 4 leçons au total.

Quand une jointure renvoie trop de lignes

L'une des questions d'entretien les plus révélatrices semble anodine : « une jointure peut-elle renvoyer plus de lignes que la plus grande table ? » La réponse est oui ; ce phénomène s'appelle la multiplication des lignes.

Les candidats qui répondent « une jointure ne fait que combiner des tables » passent à côté du problème. Ceux qui savent prévoir le nombre exact de lignes sont recrutés. Cette leçon vous apprend à faire cette prévision.

La cause : les correspondances un-à-plusieurs

La multiplication des lignes se produit lorsqu'une ligne de gauche correspond à plusieurs lignes de droite. Chaque correspondance produit une ligne de sortie distincte.

Avec des clients et des commandes, Ada (un client) a deux commandes. La jointure produit une ligne par commande, Ada apparaît donc deux fois. Les champs du client se répètent ; seuls les champs de la commande diffèrent.

SELECT c.name, o.amount
FROM customers c
JOIN orders o ON o.customer_id = c.id;
-- Ada appears twice (she has 2 orders)
-- name | amount
-- Ada  | 50
-- Ada  | 20
-- Bob  | 99

Compter les lignes de sortie

Le nombre de lignes de sortie correspond à la somme des correspondances pour chaque ligne de gauche, et non au nombre de clients.

  • Ada -> 2 commandes -> 2 lignes
  • Bob -> 1 commande -> 1 ligne
  • Cleo -> 0 commande -> 0 ligne (supprimée par INNER JOIN)

Total = 3 lignes, même si la table des clients contient également 3 lignes. Si Ada passe à 10 commandes, le résultat atteint 11 lignes.

Les correspondances plusieurs-à-plusieurs explosent

La multiplication des lignes s'amplifie lorsque les deux côtés comportent plusieurs correspondances pour la même clé. Si la clé K apparaît 3 fois à gauche et 4 fois à droite, la jointure produit 3 x 4 = 12 lignes pour cette clé.

C'est ainsi qu'une jointure apparemment petite peut produire des millions de lignes. Les recruteurs aiment fournir des clés en double des deux côtés pour vérifier que vous repérez la multiplication.

-- left has 3 rows with tag 'A', right has 4 rows with tag 'A'
SELECT l.id, r.id
FROM left_t l
JOIN right_t r ON r.tag = l.tag;
-- tag 'A' alone yields 3 * 4 = 12 output rows

Le piège de l'agrégation

Voici le bug que les recruteurs mettent le plus souvent en place. Vous joignez les commandes aux lignes de commande pour obtenir les détails des articles, puis vous additionnez le montant de la commande avec SUM. Comme chaque commande se multiplie en plusieurs lignes d'article, le montant de la commande est compté une fois par article.

La somme est alors fortement surévaluée. La requête semble correcte et s'exécute même sans erreur, ce qui la rend dangereuse.

-- BUG: order.amount duplicated across items
SELECT SUM(o.amount) AS total
FROM orders o
JOIN order_items i ON i.order_id = o.id;
-- a 3-item order counts o.amount 3 times

Voir la surévaluation

Supposons qu'une commande ait un montant de 100 et trois lignes d'article. La jointure produit trois lignes, chacune portant le montant 100. SUM(o.amount) renvoie 300, et non 100.

La solution consiste à agréger à la bonne granularité : additionnez les articles, ou additionnez séparément les commandes distinctes. N'additionnez jamais la valeur d'un parent sur une jointure avec multiplication des lignes enfants.

o.id | o.amount | i.id
7    | 100      | 71
7    | 100      | 72
7    | 100      | 73
-- SUM(o.amount) = 300  (WRONG, should be 100)

Correction 1 : agréger d'abord les éléments enfants

La solution la plus propre consiste à préagréger le côté « plusieurs » dans une sous-requête ou un CTE, afin que chaque parent corresponde exactement à une ligne résumée. Pas de multiplication des lignes, pas de surévaluation.

Ici, nous regroupons les articles en une ligne par commande avant d'effectuer la jointure : le montant du parent n'est donc jamais dupliqué.

SELECT o.id, o.amount, i.item_count
FROM orders o
JOIN (
  SELECT order_id, COUNT(*) AS item_count
  FROM order_items
  GROUP BY order_id
) i ON i.order_id = o.id;

Correction 2 : COUNT(DISTINCT) et sommes conditionnelles

Si vous devez agréger après une jointure avec multiplication des lignes, comptez ou additionnez à la bonne granularité. Utilisez COUNT(DISTINCT o.id) pour compter les commandes plutôt que les lignes d'article.

Remarque : SUM(DISTINCT o.amount) n'est PAS une solution sûre, car deux commandes différentes peuvent légitimement avoir le même montant et seraient fusionnées. La préagrégation est plus fiable.

SELECT COUNT(DISTINCT o.id)   AS num_orders,
       COUNT(i.id)            AS num_items
FROM orders o
JOIN order_items i ON i.order_id = o.id;

Détecter la multiplication des lignes avant qu'elle ne pose problème

Voici un diagnostic rapide apprécié des recruteurs : vérifiez que la clé de jointure est unique du côté que vous pensez être le côté « un ». Si le nombre de clés distinctes est inférieur au nombre de lignes, ce côté contient des doublons et provoquera une multiplication des lignes.

-- if this returns rows, order_id is NOT unique in order_items
SELECT order_id, COUNT(*) AS n
FROM order_items
GROUP BY order_id
HAVING COUNT(*) > 1;

Vérifier la granularité avec un comptage

Avant de faire confiance à une agrégation sur un résultat joint, vérifiez la cohérence du nombre de lignes. Une astuce rapide consiste à comparer le nombre de lignes jointes au nombre de lignes de la table dont vous attendez la granularité.

Si COUNT(*) sur la jointure est supérieur à COUNT(*) de la table des commandes, la jointure a multiplié les lignes et toute agrégation par commande est susceptible d'être faussée. Cette vérification sur une seule ligne a sauvé de nombreuses réponses d'entretien.

-- joined rows should equal order count if no fan-out
SELECT COUNT(*) AS joined_rows
FROM orders o
JOIN order_items i ON i.order_id = o.id;

SELECT COUNT(*) AS order_rows FROM orders;
-- joined_rows > order_rows  =>  fan-out present

La multiplication des lignes n'est pas toujours un bug

Parfois, vous voulez une ligne par élément enfant. Répertorier chaque ligne de commande avec les informations de sa commande est une multiplication correcte. La compétence consiste à connaître votre granularité cible : combien de lignes chaque entité doit-elle produire ?

Énoncez la granularité avant d'écrire la requête. « Je veux une ligne par ligne de commande » ou « une ligne par commande » détermine si la multiplication des lignes est une fonctionnalité ou un bug.

Vérification rapide

Prévoyez le résultat d'une jointure un-à-plusieurs.

Récapitulatif : multiplication des lignes

Ce qu'il faut retenir :

  • Une jointure produit une ligne par paire correspondante ; les correspondances un-à-plusieurs dupliquent donc le côté « un ».
  • Les clés plusieurs-à-plusieurs se multiplient : 3 x 4 = 12 lignes pour cette clé.
  • Agréger une valeur parente sur une jointure avec multiplication des lignes fausse à la hausse les sommes et les comptages.
  • Corrigez le problème en préagrégeant les éléments enfants, ou en comptant et additionnant à la bonne granularité (par exemple avec COUNT(DISTINCT)).
  • Énoncez toujours d'abord la granularité visée ; la multiplication des lignes n'est un bug que lorsqu'elle ne la respecte pas.

Questions Fréquemment Posées

La leçon « Multiplication des lignes lors d’une jointure » est-elle gratuite ?

Oui — le texte complet de « Multiplication des lignes lors d’une jointure » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Coding Interview Prep, passe à CoddyKit PRO. Le cours Coding Interview Prep comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Multiplication des lignes lors d’une jointure » ?

Pourquoi une jointure peut renvoyer plus de lignes que l’une ou l’autre table et comment les recruteurs le vérifient Tu pratiques Coding Interview Prep avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Coding Interview Prep ?

Aucune expérience préalable n'est requise. Coding Interview Prep sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Multiplication des lignes lors d’une jointure » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Coding Interview Prep ?

Oui. Chaque leçon Coding Interview Prep inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Comment INNER JOIN met les lignes en correspondance
  2. ON ou WHERE dans les jointures
  3. Multiplication des lignes lors d’une jointure
  4. Joindre trois tables ou plus
← Retour à Coding Interview Prep