0Pricing
Coding Interview Prep · Lektion

JOIN-Fan-out und Zeilenvervielfachung

Warum ein JOIN mehr Zeilen zurückgeben kann als jede der beiden Tabellen und wie Interviewer dies prüfen

JOIN-Fan-out und Zeilenvervielfachung ist eine kostenlose Coding Interview Prep-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Coding Interview Prep-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Coding Interview Prep-Kurs umfasst insgesamt 4 Lektionen.

Wenn ein JOIN zu viele Zeilen zurückgibt

Eine der aufschlussreichsten Fragen im Interview klingt harmlos: „Kann ein JOIN mehr Zeilen zurückgeben als die größere Tabelle?“ Die Antwort lautet ja. Dieses Phänomen heißt Fan-out oder Zeilenvervielfachung.

Wer sagt, „ein JOIN kombiniert einfach Tabellen“, übersieht diesen Effekt. Wer die genaue Zeilenanzahl vorhersagen kann, hebt sich positiv ab. Diese Lektion entwickelt genau diese Fähigkeit.

Die Ursache: Zuordnungen von einer zu vielen Zeilen

Fan-out entsteht, wenn eine Zeile auf der linken Seite zu vielen Zeilen auf der rechten Seite passt. Jede Übereinstimmung erzeugt eine eigene Ergebniszeile.

Bei customers und orders hat Ada (eine Kundin) zwei Bestellungen. Der JOIN erzeugt eine Zeile pro Bestellung, daher erscheint Ada doppelt. Die Kundenfelder wiederholen sich, nur die Bestellfelder unterscheiden sich.

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

Die Ergebniszeilen zählen

Die Anzahl der Ergebniszeilen entspricht der Summe der Übereinstimmungen pro linker Zeile, nicht der Anzahl der Kunden.

  • Ada -> 2 Bestellungen -> 2 Zeilen
  • Bob -> 1 Bestellung -> 1 Zeile
  • Cleo -> 0 Bestellungen -> 0 Zeilen (durch INNER JOIN entfernt)

Insgesamt sind es 3 Zeilen, obwohl customers ebenfalls 3 Zeilen enthält. Ändern Sie Adas Anzahl auf 10 Bestellungen, steigt das Ergebnis auf 11 Zeilen.

Viele-zu-viele-Verknüpfungen explodieren

Fan-out verstärkt sich, wenn beide Seiten für denselben Schlüssel mehrere Übereinstimmungen haben. Wenn der Schlüssel K links dreimal und rechts viermal vorkommt, erzeugt der JOIN für diesen Schlüssel 3 x 4 = 12 Zeilen.

So kann ein scheinbar kleiner JOIN auf Millionen von Zeilen anwachsen. Interviewer verwenden gern doppelte Schlüssel auf beiden Seiten, um zu prüfen, ob Sie die Vervielfachung erkennen.

-- 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

Die Aggregationsfalle

Hier ist der Fehler, den Interviewer am häufigsten einbauen. Sie verknüpfen orders mit order_items, um Artikeldetails zu erhalten, und bilden anschließend die SUMME des Bestellbetrags. Da sich jede Bestellung auf mehrere Artikelzeilen vervielfacht, wird der Bestellbetrag einmal pro Artikel gezählt.

Die SUMME ist nun stark überhöht. Die Abfrage sieht korrekt aus und läuft sogar erfolgreich, was sie so gefährlich macht.

-- 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

Die Aufblähung sichtbar machen

Angenommen, eine Bestellung hat den Betrag 100 und drei Artikelpositionen. Der JOIN erzeugt drei Zeilen, die jeweils den Betrag 100 enthalten. SUM(o.amount) liefert 300 statt 100.

Die Lösung besteht darin, auf der richtigen Granularität zu aggregieren: Summieren Sie die Artikel oder summieren Sie unterschiedliche Bestellungen separat. Bilden Sie niemals die SUMME eines Elternwerts über einen JOIN mit vervielfachten Kindzeilen.

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

Lösung 1: Zuerst die Kindtabelle aggregieren

Die sauberste Lösung besteht darin, die Viele-Seite in einer Unterabfrage oder CTE vorab zu aggregieren, sodass jede übergeordnete Zeile genau eine zusammengefasste Zeile zugeordnet bekommt. Kein Fan-out, keine Aufblähung.

Hier fassen wir die Artikel vor dem JOIN zu einer Zeile pro Bestellung zusammen, sodass der Bestellbetrag niemals dupliziert wird.

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;

Lösung 2: COUNT(DISTINCT) und bedingte Summen

Wenn Sie nach einem JOIN mit Fan-out aggregieren müssen, zählen oder summieren Sie auf der richtigen Granularität. Verwenden Sie COUNT(DISTINCT o.id), um Bestellungen statt Artikelzeilen zu zählen.

Beachten Sie: SUM(DISTINCT o.amount) ist KEINE sichere Lösung, da zwei verschiedene Bestellungen denselben Betrag haben können und dann zusammengefasst würden. Eine Voraggregation ist zuverlässiger.

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 erkennen, bevor er zum Problem wird

Eine schnelle Diagnose, die Interviewer gern sehen: Prüfen Sie, ob der Join-Schlüssel auf der Seite, die Ihrer Erwartung nach die „Eins“-Seite ist, eindeutig ist. Wenn die Anzahl der unterschiedlichen Schlüssel kleiner als die Zeilenanzahl ist, enthält diese Seite Duplikate und führt zu 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;

Die Granularität mit einer Zählung überprüfen

Bevor Sie einer Aggregation über ein verknüpftes Ergebnis vertrauen, prüfen Sie sicherheitshalber die Zeilenanzahl. Ein schneller Trick ist, die Anzahl der verknüpften Zeilen mit der Anzahl der Zeilen in der Tabelle zu vergleichen, deren Granularität Sie erwarten.

Wenn COUNT(*) über dem JOIN größer ist als COUNT(*) von orders, hat der JOIN einen Fan-out erzeugt und jede Aggregation pro Bestellung ist gefährdet. Diese einzeilige Prüfung hat schon viele Antworten im Interview gerettet.

-- 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

Fan-out ist nicht immer ein Fehler

Manchmal möchten Sie eine Zeile pro Kindzeile. Jede Artikelposition zusammen mit den Kopfdaten ihrer Bestellung aufzulisten, ist ein korrekter Fan-out. Entscheidend ist, dass Sie Ihre gewünschte Granularität kennen: Wie viele Zeilen soll eine Entität erzeugen?

Legen Sie die Granularität fest, bevor Sie die Abfrage schreiben. „Ich möchte eine Zeile pro Bestellposition“ im Gegensatz zu „eine Zeile pro Bestellung“ entscheidet, ob Fan-out ein Merkmal oder ein Fehler ist.

Schnelltest

Sagen Sie das Ergebnis eines Eins-zu-viele-JOINs voraus.

Zusammenfassung: Fan-out und Zeilenvervielfachung

Das sollten Sie sich merken:

  • Ein JOIN erzeugt eine Zeile pro passendem Paar, daher vervielfachen Eins-zu-viele-Zuordnungen die „Eins“-Seite.
  • Viele-zu-viele-Schlüssel werden multipliziert: 3 x 4 = 12 Zeilen für diesen Schlüssel.
  • Die Aggregation eines Elternwerts über einen JOIN mit Fan-out bläht Summen und Zählungen auf.
  • Beheben Sie das Problem, indem Sie die Kindtabelle vorab aggregieren oder auf der richtigen Granularität zählen bzw. summieren, zum Beispiel mit COUNT(DISTINCT).
  • Geben Sie immer zuerst die gewünschte Granularität an. Fan-out ist nur dann ein Fehler, wenn er gegen diese Vorgabe verstößt.

Häufig gestellte Fragen

Ist die Lektion „JOIN-Fan-out und Zeilenvervielfachung“ kostenlos?

Ja — der vollständige Text von „JOIN-Fan-out und Zeilenvervielfachung“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Coding Interview Prep-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Coding Interview Prep-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „JOIN-Fan-out und Zeilenvervielfachung“?

Warum ein JOIN mehr Zeilen zurückgeben kann als jede der beiden Tabellen und wie Interviewer dies prüfen Du übst Coding Interview Prep mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Coding Interview Prep zu starten?

Keine Vorkenntnisse erforderlich. Coding Interview Prep auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „JOIN-Fan-out und Zeilenvervielfachung“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Coding Interview Prep-Lektion Code schreiben und ausführen?

Ja. Jede Coding Interview Prep-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Wie INNER JOIN Zeilen zusammenführt
  2. ON oder WHERE bei JOINs
  3. JOIN-Fan-out und Zeilenvervielfachung
  4. Drei oder mehr Tabellen verknüpfen
← Zurück zu Coding Interview Prep