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
- So funktionieren rekursive CTEs
- Einen Kategoriebaum durchlaufen
- Sequenzen und Reihen erzeugen
- Endlosschleifen vermeiden