Join fan-out en rijvermenigvuldiging
Waarom een join meer rijen kan opleveren dan een van beide tabellen en hoe interviewers dit testen
Join fan-out en rijvermenigvuldiging is een gratis Voorbereiding op programmeerinterviews-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Voorbereiding op programmeerinterviews. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Voorbereiding op programmeerinterviews bevat in totaal 4 lessen.
Wanneer een koppeling te veel rijen oplevert
Een van de meest onthullende interviewvragen klinkt onschuldig: "kan een koppeling meer rijen opleveren dan de grootste tabel?" Het antwoord is ja. Dit verschijnsel heet fan-out of rijvermenigvuldiging.
Kandidaten die zeggen "een koppeling combineert gewoon tabellen" missen dit. Kandidaten die het exacte aantal rijen kunnen voorspellen, worden aangenomen. Deze les ontwikkelt die voorspellingsvaardigheid.
De oorzaak: één-op-veel-overeenkomsten
Fan-out ontstaat wanneer één rij aan de linkerkant overeenkomt met veel rijen aan de rechterkant. Elke overeenkomst levert een afzonderlijke uitvoerrij op.
Bij customers en orders heeft Ada (één klant) twee bestellingen. De koppeling levert één rij per bestelling op, dus Ada komt twee keer voor. De klantvelden worden herhaald; alleen de ordervelden verschillen.
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 | 99Het aantal uitvoerrijen tellen
Het aantal uitvoerrijen is gelijk aan de som van de overeenkomsten per rij aan de linkerkant, niet aan het aantal klanten.
- Ada -> 2 bestellingen -> 2 rijen
- Bob -> 1 bestelling -> 1 rij
- Cleo -> 0 bestellingen -> 0 rijen (verwijderd door INNER JOIN)
Totaal = 3 rijen, ook al heeft customers eveneens 3 rijen. Verander Ada naar 10 bestellingen en het resultaat springt naar 11 rijen.
Veel-op-veel explodeert
Fan-out wordt sterker wanneer beide kanten meerdere overeenkomsten voor dezelfde sleutel hebben. Als sleutel K 3 keer aan de linkerkant en 4 keer aan de rechterkant voorkomt, levert de koppeling voor die sleutel 3 x 4 = 12 rijen op.
Zo kan een ogenschijnlijk kleine koppeling uitgroeien tot miljoenen rijen. Interviewers geven graag dubbele sleutels aan beide kanten om te zien of je de vermenigvuldiging opmerkt.
-- 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 rowsDe aggregatievalkuil
Dit is de fout die interviewers het vaakst inbouwen. Je koppelt orders aan order_items om itemdetails op te halen en telt daarna het orderbedrag op met SUM. Omdat elke bestelling wordt vermenigvuldigd naar meerdere itemrijen, wordt het orderbedrag één keer per item geteld.
De SUM is nu enorm opgeblazen. De query ziet er correct uit en wordt zelfs uitgevoerd, en juist dat maakt deze fout gevaarlijk.
-- 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 timesDe opblazing in beeld
Stel dat één bestelling een bedrag van 100 en drie orderregels heeft. De koppeling levert drie rijen op, elk met bedrag 100. SUM(o.amount) retourneert 300, niet 100.
De oplossing is aggregeren op de juiste granulariteit: tel de items op, of tel afzonderlijke bestellingen afzonderlijk op. Gebruik nooit SUM voor een waarde uit een bovenliggende tabel over een gekoppelde onderliggende tabel die fan-out veroorzaakt.
o.id | o.amount | i.id
7 | 100 | 71
7 | 100 | 72
7 | 100 | 73
-- SUM(o.amount) = 300 (WRONG, should be 100)Oplossing 1: aggregeer de onderliggende tabel eerst
De eenvoudigste oplossing is om de veel-kant vooraf te aggregeren in een subquery of CTE, zodat elke bovenliggende rij precies met één samengevatte rij overeenkomt. Geen fan-out en geen opblazing.
Hier brengen we de items terug tot één rij per bestelling voordat we de koppeling maken, zodat het bedrag van de bovenliggende rij nooit wordt gedupliceerd.
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;Oplossing 2: COUNT(DISTINCT) en voorwaardelijke sommen
Als je na een koppeling met fan-out moet aggregeren, tel of som dan op de juiste granulariteit. Gebruik COUNT(DISTINCT o.id) om bestellingen te tellen in plaats van itemrijen.
Let op: SUM(DISTINCT o.amount) is GEEN veilige oplossing, omdat twee verschillende bestellingen legitiem hetzelfde bedrag kunnen hebben en dan samengevoegd zouden worden. Vooraf aggregeren is betrouwbaarder.
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;Fan-out detecteren voordat het problemen geeft
Een snelle diagnose waar interviewers van houden: controleer of de koppelingssleutel uniek is aan de kant die volgens jou de "één" is. Als het aantal unieke sleutels kleiner is dan het aantal rijen, bevat die kant dubbele waarden en veroorzaakt deze fan-out.
-- 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;Je granulariteit controleren met een telling
Controleer de plausibiliteit van het aantal rijen voordat je een aggregatie over een gekoppeld resultaat vertrouwt. Een snelle methode is het aantal gekoppelde rijen te vergelijken met het aantal rijen in de tabel waarvan je verwacht dat die de granulariteit bepaalt.
Als COUNT(*) over de koppeling groter is dan COUNT(*) van orders, heeft de koppeling fan-out veroorzaakt en loopt elke aggregatie per bestelling risico. Deze controle van één regel heeft al veel antwoorden in interviews gered.
-- 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 presentFan-out is niet altijd een bug
Soms wil je één rij per onderliggende rij. Elke orderregel met de kopgegevens van de bestelling tonen is dan correcte fan-out. De vaardigheid bestaat uit het kennen van je gewenste granulariteit: hoeveel rijen moet één entiteit opleveren?
Geef de granulariteit aan voordat je de query schrijft. "Ik wil één rij per orderregel" tegenover "één rij per bestelling" bepaalt of fan-out een functionaliteit of een bug is.
Korte controle
Voorspel de uitvoer van een één-op-veel-koppeling.
Samenvatting: fan-out en rijvermenigvuldiging
Onthoud:
- Een koppeling levert één rij per overeenkomend paar, dus één-op-veel-overeenkomsten dupliceren de kant met "één".
- Veel-op-veel-sleutels vermenigvuldigen: 3 x 4 = 12 rijen voor die sleutel.
- Een waarde uit een bovenliggende tabel aggregeren over een koppeling met fan-out blaast sommen en tellingen op.
- Los dit op door de onderliggende tabel vooraf te aggregeren, of door op de juiste granulariteit te tellen of op te tellen, bijvoorbeeld met
COUNT(DISTINCT). - Geef altijd eerst de beoogde granulariteit aan; fan-out is alleen een bug als deze daarmee in strijd is.
Leer Voorbereiding op programmeerinterviews met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 90
- Lessen
- 360
Veelgestelde vragen
Is de les “Join fan-out en rijvermenigvuldiging” gratis?
Ja — de volledige tekst van “Join fan-out en rijvermenigvuldiging” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Voorbereiding op programmeerinterviews wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Voorbereiding op programmeerinterviews bevat in totaal 4 lessen.
Wat leer ik in “Join fan-out en rijvermenigvuldiging”?
Waarom een join meer rijen kan opleveren dan een van beide tabellen en hoe interviewers dit testen Je oefent met Voorbereiding op programmeerinterviews door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Voorbereiding op programmeerinterviews te beginnen?
Ervaring vooraf is niet nodig. Voorbereiding op programmeerinterviews op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.
Hoe lang duurt de les “Join fan-out en rijvermenigvuldiging”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Voorbereiding op programmeerinterviews?
Ja. Elke les over Voorbereiding op programmeerinterviews bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Hoe INNER JOIN rijen koppelt
- ON versus WHERE bij joins
- Join fan-out en rijvermenigvuldiging
- Drie of meer tabellen koppelen