0Pricing
SQL Academy · Lektion

Einen Kategoriebaum durchlaufen

Übergeordnete und untergeordnete Bäume vollständig erweitern

Einen Kategoriebaum durchlaufen ist eine kostenlose SQL Academy-Lektion auf CoddyKit. Dies ist Lektion 2 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 SQL Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der SQL Academy-Kurs umfasst insgesamt 4 Lektionen.

Was ist ein Kategoriebaum?

Viele reale Datensätze weisen eine Eltern-Kind-Beziehung auf. Ein Produktkatalog kann beispielsweise Kategorien wie Elektronik → Telefone → Smartphones enthalten. Jeder Knoten hat ein übergeordnetes Element, wodurch eine Baumstruktur entsteht.

In SQL wird dies typischerweise in einer Tabelle mit Selbstreferenz gespeichert: Jede Zeile hat eine id und eine parent_id, die auf eine andere Zeile derselben Tabelle verweist.

CREATE TABLE categories (
  id       INT PRIMARY KEY,
  name     VARCHAR(100) NOT NULL,
  parent_id INT REFERENCES categories(id)
);

Beispieldaten für Kategorien

Befüllen Sie einen kleinen Kategoriebaum. Der Wurzelknoten hat parent_id = NULL, da er kein übergeordnetes Element besitzt. Jeder andere Knoten verweist mit einem Wert ungleich null in parent_id auf sein übergeordnetes Element.

INSERT INTO categories (id, name, parent_id) VALUES
  (1, 'Electronics',   NULL),
  (2, 'Phones',         1),
  (3, 'Laptops',        1),
  (4, 'Smartphones',    2),
  (5, 'Feature Phones', 2),
  (6, 'Gaming Laptops', 3),
  (7, 'Ultrabooks',     3);

Das Problem einfacher Abfragen

Eine einfache SELECT-Abfrage kann immer nur eine Ebene abrufen. Um drei Ebenen tief vorzudringen, bräuchten Sie drei separate Abfragen oder drei Self-Joins, was mit wachsendem Baum unhandhabbar wird.

WITH RECURSIVE löst dieses Problem, indem eine Abfrage auf ihre eigene Ausgabe verweisen kann und Ebene für Ebene durchläuft, bis keine neuen Zeilen mehr gefunden werden.

-- This only shows direct children of Electronics (level 1)
SELECT id, name
FROM   categories
WHERE  parent_id = 1;

Aufbau von WITH RECURSIVE

Eine rekursive CTE besteht aus zwei Teilen, die durch UNION ALL getrennt sind:

1. Ankerteil — ein normales SELECT, das die Ausgangszeilen liefert.

2. Rekursiver Teil — ein SELECT, das die CTE wieder mit sich selbst verknüpft und in jeder Iteration die nächste Ebene erzeugt.

Die Engine wiederholt den rekursiven Teil, bis er null Zeilen zurückgibt.

WITH RECURSIVE cte AS (
  -- Anchor: starting rows
  SELECT ...
  UNION ALL
  -- Recursive: join cte to base table
  SELECT ... FROM base_table JOIN cte ON ...
)
SELECT * FROM cte;

Den vollständigen Baum von der Wurzel aus durchlaufen

Beginnen Sie bei der Wurzel (dort, wo parent_id IS NULL gilt), und durchlaufen Sie alle Nachkommen. Der rekursive Teil verknüpft jede bisher gesammelte Zeile anhand der Eltern-Kind-Beziehung wieder mit categories.

WITH RECURSIVE category_tree AS (
  -- Anchor: root nodes
  SELECT id, name, parent_id, 1 AS depth
  FROM   categories
  WHERE  parent_id IS NULL

  UNION ALL

  -- Recursive: children of current level
  SELECT c.id, c.name, c.parent_id, ct.depth + 1
  FROM   categories      c
  JOIN   category_tree   ct ON ct.id = c.parent_id
)
SELECT id, name, depth
FROM   category_tree
ORDER  BY depth, id;

Den Pfad verfolgen

Es ist hilfreich, den vollständigen Pfad von der Wurzel zu jedem Knoten zu speichern. Sie können beim tieferen Rekursionsschritt eine path-Zeichenkette aufbauen, indem Sie die Namen der Vorfahren verketten.

Damit lassen sich Breadcrumb-Navigationen wie Elektronik / Telefone / Smartphones leicht anzeigen.

WITH RECURSIVE category_tree AS (
  SELECT id, name, parent_id,
         name AS path
  FROM   categories
  WHERE  parent_id IS NULL

  UNION ALL

  SELECT c.id, c.name, c.parent_id,
         ct.path || ' / ' || c.name
  FROM   categories    c
  JOIN   category_tree ct ON ct.id = c.parent_id
)
SELECT id, name, path
FROM   category_tree
ORDER  BY path;

Bei einem bestimmten Knoten beginnen

Sie müssen nicht bei der Wurzel beginnen. Indem Sie die WHERE-Klausel des Ankers ändern, können Sie den Teilbaum jedes Knotens durchlaufen. Hier beginnen Sie bei Telefone (id = 2) und rufen alle Nachkommen ab.

WITH RECURSIVE subtree AS (
  SELECT id, name, parent_id, 0 AS depth
  FROM   categories
  WHERE  id = 2          -- start at Phones

  UNION ALL

  SELECT c.id, c.name, c.parent_id, s.depth + 1
  FROM   categories c
  JOIN   subtree    s ON s.id = c.parent_id
)
SELECT id, name, depth
FROM   subtree
ORDER  BY depth, id;

Aufwärts durchlaufen: Alle Vorfahren finden

Der Baum kann auch in umgekehrter Richtung durchlaufen werden — von einem Blattknoten aufwärts bis zur Wurzel. Kehren Sie einfach die Verknüpfung um, sodass Sie parent_id aufwärts statt abwärts verfolgen. Das ist nützlich, wenn Sie die vollständige Breadcrumb-Navigation für einen bekannten Blattknoten benötigen.

WITH RECURSIVE ancestors AS (
  SELECT id, name, parent_id
  FROM   categories
  WHERE  id = 4          -- start at Smartphones

  UNION ALL

  SELECT c.id, c.name, c.parent_id
  FROM   categories c
  JOIN   ancestors  a ON a.parent_id = c.id
)
SELECT id, name
FROM   ancestors
ORDER  BY id;

Eine eingerückte Darstellung hinzufügen

Eine verbreitete UI-Darstellung besteht darin, untergeordnete Knoten visuell einzurücken. Mit REPEAT (oder LPAD) und der Spalte depth können Sie jedem Namen Leerzeichen voranstellen und so eine textbasierte Baumansicht erzeugen.

WITH RECURSIVE category_tree AS (
  SELECT id, name, parent_id, 0 AS depth
  FROM   categories
  WHERE  parent_id IS NULL

  UNION ALL

  SELECT c.id, c.name, c.parent_id, ct.depth + 1
  FROM   categories    c
  JOIN   category_tree ct ON ct.id = c.parent_id
)
SELECT
  REPEAT('    ', depth) || name AS indented_name,
  depth
FROM   category_tree
ORDER  BY path;

Endlosschleifen verhindern

Falls Ihre Daten einen Zyklus enthalten (A ist Elternknoten von B, B ist Elternknoten von A), läuft die Rekursion unendlich weiter und stürzt ab. Sie können dies verhindern, indem Sie besuchte IDs in einem Array speichern und stoppen, sobald die aktuelle ID bereits enthalten ist.

WITH RECURSIVE safe_tree AS (
  SELECT id, name, parent_id,
         ARRAY[id] AS visited
  FROM   categories
  WHERE  parent_id IS NULL

  UNION ALL

  SELECT c.id, c.name, c.parent_id,
         st.visited || c.id
  FROM   categories c
  JOIN   safe_tree  st ON st.id = c.parent_id
  WHERE  c.id <> ALL(st.visited)   -- stop if already seen
)
SELECT id, name FROM safe_tree;

Nachkommen pro Knoten zählen

Sobald Sie den vollständigen Baum haben, können Sie ihn aggregieren. Hier zählen Sie, wie viele Nachkommen jeder Knoten hat, indem Sie die Kindzeilen wieder anhand der Liste der Vorfahren gruppieren. Das ist nützlich, um in einem Navigationsmenü neben den Kategorienamen die Anzahl der Elemente anzuzeigen.

WITH RECURSIVE category_tree AS (
  SELECT id, name, parent_id, id AS root_id
  FROM   categories
  WHERE  parent_id IS NULL

  UNION ALL

  SELECT c.id, c.name, c.parent_id, ct.root_id
  FROM   categories    c
  JOIN   category_tree ct ON ct.id = c.parent_id
)
SELECT
  root_id,
  COUNT(*) - 1 AS descendant_count
FROM   category_tree
GROUP  BY root_id
ORDER  BY root_id;

Schnelltest

Testen Sie Ihr Verständnis von Abfragen für rekursive Kategoriebaumstrukturen.

Zusammenfassung der Lektion

In dieser Lektion haben Sie gelernt, wie Sie eine Tabelle mit Selbstreferenzen für Kategorien mithilfe von WITH RECURSIVE durchlaufen.

Die wichtigsten Erkenntnisse:

- Der Ankerteil wählt die Ausgangsknoten aus (normalerweise die Wurzel).

- Der rekursive Teil verknüpft die CTE wieder mit der Basistabelle, um die nächste Ebene zu finden.

- Fügen Sie eine Spalte depth hinzu, um zu verfolgen, wie viele Ebenen tief jeder Knoten liegt.

- Bauen Sie eine path-Zeichenkette auf, um Breadcrumb-Navigationen zu erzeugen.

- Durchlaufen Sie den Baum aufwärts, indem Sie parent_id in umgekehrter Richtung verfolgen, um alle Vorfahren zu finden.

- Verwenden Sie ein visited-Array, um Zyklen in fehlerhaften Daten zu verhindern.

Häufig gestellte Fragen

Ist die Lektion „Einen Kategoriebaum durchlaufen“ kostenlos?

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

Was lerne ich in „Einen Kategoriebaum durchlaufen“?

Übergeordnete und untergeordnete Bäume vollständig erweitern Du übst SQL Academy 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 SQL Academy zu starten?

Keine Vorkenntnisse erforderlich. SQL Academy 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 2 von 4.

Wie lange dauert die Lektion „Einen Kategoriebaum durchlaufen“?

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 SQL Academy-Lektion Code schreiben und ausführen?

Ja. Jede SQL Academy-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. So funktionieren rekursive CTEs
  2. Einen Kategoriebaum durchlaufen
  3. Sequenzen und Reihen erzeugen
  4. Endlosschleifen vermeiden
← Zurück zu SQL Academy