← CS Lab Databases & Data Modeling / SQL JOINs Open standalone ↗

A JOIN combines rows from two tables into one result, matching them on a shared key. The join type decides what happens to rows that find no partner.

Where you meet it

What it does

Relational data is deliberately split across tables to avoid repeating it. A join reassembles it on demand: it pairs each row of the left table with matching rows of the right table, following the rule you give in ON.

The join type is just a rule for partnerless rows — and a WHERE on the right table quietly turns your LEFT JOIN back into an INNER one.

How it works

The ON condition is checked for every possible pair of rows. Pairs where it's true become result rows. What sets the join types apart is how they treat rows with no match:

-- users(id, name), orders(id, user_id, item)
SELECT u.name, o.item
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;

-- INNER drops Dan (no order) and order #105 (no user).
-- LEFT keeps Dan, with item = NULL.

Watch out

  • No ON → accidental Cartesian product. Forgetting the condition (or a comma-join with no WHERE) pairs every row with every other — millions of rows from a small slip.
  • LEFT JOIN + a WHERE on the right table silently becomes an INNER JOIN. A filter like WHERE o.status = 'paid' rejects the NULL rows you were trying to keep. Put that condition in the ON clause instead.
  • Duplicate rows from one-to-many. If one left row matches several right rows, the left row repeats once per match — easy to over-count in a SUM or COUNT.

Go deeper

Ein JOIN verbindet Zeilen aus zwei Tabellen zu einem Ergebnis und matcht sie über einen gemeinsamen Schlüssel. Der Join-Typ entscheidet, was mit partnerlosen Zeilen passiert.

Wo es vorkommt

Was es tut

Relationale Daten liegen bewusst auf Tabellen verteilt, um Wiederholung zu vermeiden. Ein Join setzt sie auf Abruf wieder zusammen: Er paart jede Zeile der linken Tabelle mit passenden Zeilen der rechten — nach der Regel, die du in ON angibst.

Der Join-Typ ist nur eine Regel für partnerlose Zeilen — und ein WHERE auf der rechten Tabelle macht aus deinem LEFT JOIN heimlich wieder einen INNER.

Wie es funktioniert

Die ON-Bedingung wird für jedes mögliche Zeilenpaar geprüft. Paare, bei denen sie wahr ist, werden Ergebniszeilen. Die Join-Typen unterscheiden sich darin, wie sie Zeilen ohne Match behandeln:

-- users(id, name), orders(id, user_id, item)
SELECT u.name, o.item
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;

-- INNER wirft Dan (keine Order) und Order #105 (kein User) raus.
-- LEFT behält Dan, mit item = NULL.

Worauf achten

  • Kein ON → versehentliches kartesisches Produkt. Fehlt die Bedingung (oder Komma-Join ohne WHERE), wird jede Zeile mit jeder gepaart — aus einem kleinen Versehen werden Millionen Zeilen.
  • LEFT JOIN + WHERE auf der rechten Tabelle wird heimlich zum INNER JOIN. Ein Filter wie WHERE o.status = 'paid' verwirft genau die NULL-Zeilen, die du behalten wolltest. Setz die Bedingung stattdessen in die ON-Klausel.
  • Doppelte Zeilen durch 1:n. Matcht eine linke Zeile mehrere rechte, wiederholt sie sich einmal pro Match — schnell verzählt man sich in SUM oder COUNT.

Mehr dazu

Next up
Databases & Data ModelingSQL Window Functions Databases & Data ModelingSQL Subqueries & CTEs All concepts →