Menu

SQLite Self Join: Tabelle mit sich selbst verknüpfen

Wie der Self Join in SQLite funktioniert: Zeilen einer Tabelle über Aliase paaren – mit praktischen Beispielen für Mitarbeiter-Manager-Beziehungen und Hierarchien.

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

Ein Self Join ist einfach ein Join mit Aliasen

An einem Self Join ist eigentlich nichts Besonderes. Es ist ein ganz normaler JOIN, bei dem beide Seiten zufällig dieselbe Tabelle sind. Der Knackpunkt: SQLite braucht eine Möglichkeit, die beiden Kopien auseinanderzuhalten – deshalb gibst du jeder einen Alias.

Du greifst immer dann zu einem Self Join, wenn eine Zeile in einer Tabelle auf eine andere Zeile derselben Tabelle verweist. Das Paradebeispiel: eine employees-Tabelle, in der jede Zeile eine manager_id hat, die auf einen anderen Mitarbeiter zeigt:

Ada hat keinen Vorgesetzten. Boris und Cleo berichten an Ada. Diego und Esme berichten an Boris. Die gesamte Beziehung steckt in einer einzigen Tabelle – und genau hier spielt ein Self Join in SQLite seine Stärken aus.

Grundaufbau eines Self Joins

Um jeden Mitarbeiter mit dem Namen seines Managers zu verknüpfen, verbindest du die Tabelle employees mit sich selbst. Eine Kopie übernimmt die Rolle des Mitarbeiters, die andere die des Managers:

Stell es dir am besten so vor: Es sind zwei Tabellen, die sich nur denselben Speicher teilen. e ist die Mitarbeiterzeile, m die Managerzeile. Die Join-Bedingung e.manager_id = m.id bringt beide zusammen: Für jeden Mitarbeiter wird in m die Zeile gesucht, deren id mit der manager_id des Mitarbeiters übereinstimmt.

Dir ist sicher aufgefallen, dass Ada nicht im Ergebnis auftaucht. Ihre manager_id ist NULL, und ein INNER JOIN filtert Zeilen ohne Treffer einfach raus.

Auch unverknüpfte Zeilen behalten: LEFT JOIN

Wenn wirklich alle im Ergebnis stehen sollen – also auch die Personen ohne Manager –, wechselst du zu LEFT JOIN:

Jetzt taucht Ada mit NULL in der Manager-Spalte auf. Die Self-Join-Mechanik ist dieselbe – nur dass der Join-Typ genau das macht, was LEFT JOIN immer macht: alle Zeilen der linken Seite behalten und dort, wo kein Match existiert, die Lücken mit NULL füllen.

Diese Variante willst du eigentlich immer, wenn du eine Liste von Personen anzeigst. „Kein Manager" ist eine Information – die Zeile einfach wegzulassen wäre falsch.

Die Aliase sind Pflicht, kein Beiwerk

Probier denselben Self Join mal ohne Aliase aus, und SQLite hat keine Ahnung, was du eigentlich willst:

SELECT name, manager_id FROM employees JOIN employees ON manager_id = id;
-- Fehler: mehrdeutiger Spaltenname: name

Jede Spalte taucht doppelt auf — einmal pro Kopie der Tabelle — und SQLite weiß nicht, welche gemeint ist. Aliase lösen das, indem sie jeder Instanz einen eigenen Namen geben. Wähle Aliase, die die Rolle der Zeile beschreiben, nicht den Tabellennamen:

  • e und m für Mitarbeiter (employee) und Vorgesetzten (manager).
  • parent und child bei Hierarchien.
  • a und b, wenn du beliebige Paare miteinander vergleichst.

Der Alias ist letztlich der Grund, warum sich ein Self Join überhaupt sauber lesen lässt.

Zeilenpaare innerhalb einer Tabelle finden

Self Joins sind nicht nur etwas für Hierarchien. Sobald du Zeilen aus derselben Tabelle miteinander vergleichen willst, passt dieses Muster. Hier ein Beispiel mit einer Produktliste, in der wir alle Paare mit identischem Preis finden wollen:

Hier sind zwei Dinge zu beachten. Erstens ist a.price = b.price die eigentliche Verknüpfungsbedingung. Zweitens sorgt a.id < b.id dafür, dass jedes Paar nur einmal zurückkommt (statt einmal als (Tasse, Notizbuch) und nochmal als (Notizbuch, Tasse)) und dass keine Zeile mit sich selbst gepaart wird. Diesen <-Trick solltest du dir merken — er taucht immer dann auf, wenn du Paare auflisten willst.

Zwei Ebenen höher in der Hierarchie

Ein Self Join deckt genau einen Sprung in einer Hierarchie ab. Du willst zu jedem Mitarbeiter den Chef vom Chef? Dann joinst du eben dreimal:

Jeder neue Alias bringt dich eine Ebene höher im Baum. Für zwei oder drei Sprünge funktioniert das ganz gut, aber danach wird's schnell unhandlich – du müsstest schon beim Schreiben der Query die Tiefe der Hierarchie kennen und für jede Ebene einen weiteren Join ergänzen. Genau an dieser Wand setzen rekursive CTEs an.

Wann ein Self Join nicht die richtige Wahl ist

Ein self join ist dann das passende Werkzeug, wenn du Spalten von beiden Seiten der Beziehung im Ergebnis brauchst. Wenn du dagegen nur filtern willst – etwa alle Mitarbeiter finden, deren Managerin Ada ist – liest sich eine Subquery oft schöner:

Kein Alias-Gefrickel, und die Absicht ist sofort klar. Faustregel: Brauchst du Daten aus beiden Zeilen im Ergebnis? Dann Self Join. Brauchst du nur einen Wert zum Vergleichen? Dann Subquery.

Bei beliebig tiefen Hierarchien (Org-Charts, Dateibäume, verschachtelte Kommentare) skaliert keines der beiden Muster sauber. Da kommt man um rekursive CTEs nicht herum.

Als Nächstes: Subqueries

Self Joins und Subqueries lösen teils dieselben Probleme, und zu wissen, welches Werkzeug wann passt, erspart dir später viel Augenkneifen vor SQL-Code. Die nächste Seite geht tief in Subqueries rein — skalare, korrelierte und IN-Varianten — und zeigt, wo jede Form ihre Stärken ausspielt.

Häufig gestellte Fragen

Was ist ein Self Join in SQLite?

Ein Self Join ist ein ganz normaler JOIN – nur dass eine Tabelle mit sich selbst verknüpft wird. Du vergibst zwei verschiedene Aliase für dieselbe Tabelle, damit SQLite sie als zwei getrennte Zeilenquellen behandeln kann. Über eine passende Spalte werden die Zeilen dann zueinander in Beziehung gesetzt – klassisch bei Eltern-Kind-Strukturen wie Mitarbeiter und Vorgesetzter.

Warum brauche ich beim Self Join unbedingt Aliase?

Ohne Aliase weiß SQLite schlicht nicht, welche Kopie der Tabelle du meinst, wenn du einen Spaltennamen schreibst. Mit eigenen Kürzeln pro Instanz – etwa e für employee und m für manager – kannst du eindeutig e.manager_id = m.id formulieren. Die Aliase sind also kein Stilmittel, sondern Pflicht: ohne sie lässt sich das Statement gar nicht parsen.

Self Join oder lieber eine Subquery – was nehme ich wann?

Einen Self Join nimmst du, wenn du Spalten aus beiden Zeilen im Ergebnis brauchst – zum Beispiel den Namen des Mitarbeiters und den Namen seines Vorgesetzten in einer Zeile. Eine Subquery reicht, wenn du nur filtern oder einen einzelnen Wert nachschlagen willst. Bei tief verschachtelten Hierarchien passt allerdings beides nicht wirklich – dann ist eine rekursive CTE das richtige Werkzeug.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S