Menu

SQLite INNER JOIN: Zeilen aus mehreren Tabellen verknüpfen

Wie INNER JOIN in SQLite funktioniert – das mentale Modell, die ON-Klausel, drei Tabellen verknüpfen und die USING-Kurzform.

Diese Seite enthält ausführbare Editoren — bearbeiten, ausführen und Ausgabe sofort sehen.

Ein Join verbindet zwei Tabellen

Relationale Datenbanken splitten Daten bewusst auf mehrere Tabellen auf – Kunden in der einen, Bestellungen in der anderen, Produkte in einer dritten. So liegt jede Information genau an einem Ort. Sobald du aber eine echte Frage beantworten willst ("welche Kunden haben was bestellt?"), musst du die Teile wieder zusammensetzen. Genau das macht ein Join.

INNER JOIN ist das Arbeitstier unter den Joins. Er paart Zeilen aus zwei Tabellen überall dort, wo eine Bedingung zutrifft – und wirft alles andere weg.

Drei Kunden, drei Bestellungen – aber Chen hat keine Bestellung, und deshalb taucht Chen auch nicht im Ergebnis auf. Genau das ist das "Inner": Es überleben nur die Zeilen mit Treffer.

Das mentale Modell: Zeilen paaren, dann filtern

Lies einen INNER JOIN so: Nimm jede Zeile der ersten Tabelle, schau dir jede Zeile der zweiten Tabelle dazu an und behalte das Paar nur, wenn die ON-Bedingung wahr ist. Konzeptuell ist das ein riesiges Kreuzprodukt mit anschließendem Filter. SQLite macht es intern natürlich nicht so (es benutzt Indizes, wenn es kann), aber das Modell sagt richtig vorher, was am Ende rauskommt.

Ein paar Gewohnheiten, die sich hier lohnen:

  • Vergib Aliase (customers AS c), sobald du eine Tabelle mehrfach erwähnst. Das nimmt der Query optisch viel Lärm.
  • Qualifiziere Spalten (c.name, o.total), wenn beide Tabellen sie plausibel besitzen könnten.
  • Die Reihenfolge in ON o.customer_id = c.id ist egal – c.id = o.customer_id funktioniert genauso.

INNER JOIN vs JOIN

In SQLite (und im SQL-Standard) bedeutet ein nacktes JOIN schon INNER JOIN. Das INNER-Keyword ist optional.

Beide Varianten erzeugen denselben Plan und dieselben Zeilen. INNER JOIN ausgeschrieben zu lassen, ist ein kleiner Lesbarkeitsgewinn in Code, der mehrere Join-Typen mischt – die Absicht steht dann direkt neben einem LEFT JOIN ein paar Zeilen weiter.

ON vs USING

Wenn die Join-Spalten in beiden Tabellen denselben Namen tragen, ist USING (spalte) kürzer als ON a.col = b.col:

USING (customer_id) macht zwei Dinge auf einmal: Es matcht über gleiche customer_id-Werte und legt die doppelte Spalte im Ergebnis zu einer einzigen zusammen. Greif zu USING, wenn beide Seiten wirklich denselben Spaltennamen verwenden. Bleib bei ON, sobald die Namen sich unterscheiden (orders.customer_id = customers.id) oder die Bedingung mehr als eine einfache Gleichheit ist.

Drei Tabellen verknüpfen

Mehrere Joins hängst du einfach hintereinander, indem du weitere JOIN ... ON ...-Klauseln anhängst. Jede verbindet das laufende Zwischenergebnis mit einer weiteren Tabelle.

Lies es von oben nach unten: Kunden hängen an Bestellungen, Bestellungen hängen an Positionen. Jede Zeile im Ergebnis steht für eine einzelne Kunde–Bestellung–Position-Kombination. Was irgendwo entlang der Kette keinen Treffer hat, fliegt raus – die Inner-Join-Regel gilt auf jeder Stufe.

Filtern mit WHERE

ON legt fest, wie Zeilen gepaart werden. WHERE filtert das gepaarte Ergebnis. Bei einem Inner Join speziell macht es für die zurückgegebenen Zeilen keinen Unterschied, ob du eine zusätzliche Bedingung in ON oder in WHERE schreibst – die Konvention ist aber: Join-Bedingungen gehören in ON, Zeilenfilter in WHERE.

Das liest sich als "verknüpfe Kunden und Bestellungen, behalte dann nur die UK-Kunden mit einer Bestellung über 20". Zwei Aufgaben, zwei Klauseln – dein zukünftiges Ich wird's dir danken. (Sobald du anfängst, LEFT JOINs zu schreiben, wird die ON/WHERE-Unterscheidung mehr als nur Kosmetik – aber das ist Thema der nächsten Seite.)

Mehrere Bedingungen in ON

ON darf jeden booleschen Ausdruck enthalten, nicht nur eine einzige Gleichheit. Praktisch, wenn die Beziehung mehr als eine Spalte umspannt oder du die rechte Seite schon beim Joinen filtern willst.

Die stornierte Bestellung verschwindet, weil die zweite Bedingung nicht greift. Bei einem Inner Join könntest du genauso gut WHERE o.status = 'paid' schreiben und bekämst dasselbe Ergebnis. Die ON-Variante hält die "Was zählt als Treffer?"-Logik nah am Join.

Typische Stolperfallen

Ein paar Sachen, an denen man oft hängenbleibt:

  • Die ON-Klausel vergessen. FROM a INNER JOIN b ohne ON ist in SQLite ein Syntaxfehler. (Ein nacktes Komma – FROM a, b – kompiliert zwar, liefert dir aber einen Cross Join, und das war fast nie das, was du wolltest.)
  • Unerwartete Duplikate. Wenn ein Kunde drei Bestellungen hat, taucht der Kundenname dreimal im Ergebnis auf. Das ist korrektes Join-Verhalten, kein Bug. Aggregiere mit GROUP BY, wenn du eine Zeile pro Kunde willst.
  • Fehlende Zeilen. Wenn ein Kunde im Ergebnis hätte stehen sollen, aber fehlt, hat die Join-Bedingung nicht gegriffen – prüf auf NULLs in den Join-Spalten oder greif zu LEFT JOIN.
  • Mehrdeutige Spaltennamen. SELECT id FROM customers JOIN orders ON ... wirft einen Fehler, weil beide Tabellen ein id haben. Qualifiziere die Spalte: c.id oder o.id.

Als Nächstes: LEFT JOIN

INNER JOIN ist ideal, wenn fehlende Treffer "diese Zeile überspringen" bedeuten. Manchmal willst du aber jeden Kunden gelistet haben – auch die ohne Bestellungen –, mit NULLs an den Stellen, wo Daten fehlen. Genau das ist LEFT JOIN, und der kommt als Nächstes.

Häufig gestellte Fragen

Was macht ein INNER JOIN in SQLite?

INNER JOIN liefert nur die Zeilen, die in beiden Tabellen einen Treffer gemäß der ON-Bedingung haben. Zeilen, die auf einer der beiden Seiten keinen Partner finden, fallen raus. Das ist das Standardverhalten – JOIN und INNER JOIN bedeuten in SQLite dasselbe.

Was ist der Unterschied zwischen INNER JOIN und LEFT JOIN in SQLite?

INNER JOIN behält ausschließlich gematchte Zeilen. LEFT JOIN behält jede Zeile aus der linken Tabelle und füllt für die rechte Seite NULLs ein, wenn es keinen Treffer gibt. Nimm INNER JOIN, wenn fehlende Treffer 'Zeile überspringen' bedeuten – und LEFT JOIN, wenn fehlende Treffer 'trotzdem anzeigen' heißen.

Kann man in SQLite drei Tabellen mit INNER JOIN verknüpfen?

Ja – einfach eine weitere JOIN ... ON ...-Klausel anhängen. Jeder Join verbindet das aktuelle Zwischenergebnis mit einer neuen Tabelle. Eine harte Grenze gibt es nicht, aber ab vier oder fünf Tabellen leidet die Lesbarkeit – dann hilft oft ein CTE.

Wann sollte ich USING statt ON verwenden?

USING (spalte) ist eine Kurzform für den Fall, dass die Join-Spalte in beiden Tabellen denselben Namen hat. Sie ist kompakter und klappt die doppelte Spalte im Ergebnis zu einer einzigen zusammen. ON nimmst du, wenn die Spaltennamen sich unterscheiden oder die Bedingung komplexer ist.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S