Parcourir un arbre de catégories
Développez entièrement les arbres parent-enfant.
Parcourir un arbre de catégories est une leçon SQL Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage SQL Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours SQL Academy comprend 4 leçons au total.
Qu'est-ce qu'un arbre de catégories ?
De nombreux ensembles de données du monde réel présentent une relation parent-enfant. Un catalogue de produits peut comporter des catégories comme Électronique → Téléphones → Smartphones. Chaque nœud possède un parent, ce qui forme une structure arborescente.
En SQL, cela est généralement stocké dans une table autoréférente : chaque ligne possède un id et un parent_id qui pointe vers une autre ligne de la même table.
CREATE TABLE categories (
id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
parent_id INT REFERENCES categories(id)
);Exemple de données de catégories
Remplissons un petit arbre de catégories. Le nœud racine possède parent_id = NULL parce qu'il n'a pas de parent. Tous les autres nœuds pointent vers leur parent au moyen d'une valeur non nulle pour parent_id.
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);Le problème des requêtes simples
Une requête SELECT simple ne peut récupérer qu'un seul niveau à la fois. Pour atteindre trois niveaux de profondeur, vous auriez besoin de trois requêtes distinctes ou de trois auto-jointures, ce qui devient ingérable à mesure que l'arbre grandit.
WITH RECURSIVE résout ce problème en permettant à une requête de faire référence à son propre résultat et de parcourir les niveaux successivement jusqu'à ce qu'aucune nouvelle ligne ne soit trouvée.
-- This only shows direct children of Electronics (level 1)
SELECT id, name
FROM categories
WHERE parent_id = 1;Anatomie de WITH RECURSIVE
Un CTE récursif comporte deux parties séparées par UNION ALL :
1. Membre d’ancrage — un SELECT normal qui fournit les lignes de départ.
2. Membre récursif — un SELECT qui rattache le CTE à lui-même et produit le niveau suivant à chaque itération.
Le moteur répète le membre récursif jusqu’à ce qu’il ne renvoie plus aucune ligne.
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;Parcourir l’arbre complet depuis la racine
Commencez à la racine (là où parent_id IS NULL) et descendez jusqu’à chaque descendant. Le membre récursif rattache chaque ligne accumulée à categories selon la relation parent-enfant.
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;Suivre le chemin
Il est utile d’enregistrer le chemin complet de la racine jusqu’à chaque nœud. Nous pouvons construire une chaîne path en concaténant les noms des ancêtres à mesure que nous descendons dans la récursion.
Cela facilite l’affichage de fils d’Ariane tels que Électronique / Téléphones / Smartphones.
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;Commencer à partir d’un nœud précis
Vous n’êtes pas obligé de commencer à la racine. En modifiant la clause WHERE de l’ancrage, vous pouvez parcourir le sous-arbre de n’importe quel nœud. Ici, nous commençons par Téléphones (identifiant = 2) et récupérons tous ses descendants.
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;Parcourir vers le haut : trouver tous les ancêtres
Vous pouvez également parcourir l’arbre en sens inverse — en remontant d’une feuille jusqu’à la racine. Il suffit d’inverser la jointure afin de suivre parent_id vers le haut plutôt que vers le bas. Cette méthode est utile lorsque vous devez obtenir le fil d’Ariane complet d’un nœud feuille connu.
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;Ajouter un affichage indenté
Un modèle courant dans l’interface utilisateur consiste à décaler visuellement les nœuds enfants. Nous pouvons utiliser REPEAT (ou LPAD) avec la colonne depth pour préfixer chaque nom avec des espaces et produire une vue arborescente textuelle.
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;Se protéger contre les boucles infinies
Si vos données contiennent un cycle (A est le parent de B, B est le parent de A), la récursion s’exécutera indéfiniment et fera planter la base de données. Vous pouvez vous en protéger en enregistrant les identifiants déjà visités dans un tableau et en vous arrêtant lorsque l’identifiant actuel y figure déjà.
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;Compter les descendants de chaque nœud
Une fois l’arbre complet obtenu, vous pouvez l’agréger. Ici, nous comptons le nombre de descendants de chaque nœud en regroupant les lignes enfants avec la liste des ancêtres. Cette méthode est utile pour afficher le nombre d’éléments à côté des noms de catégories dans un menu de navigation.
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;Vérification rapide
Vérifiez votre compréhension des requêtes récursives sur les arbres de catégories.
Récapitulatif de la leçon
Dans cette leçon, vous avez appris à parcourir une table de catégories autoréférente à l’aide de WITH RECURSIVE.
Points essentiels :
- Le membre d’ancrage sélectionne les nœuds de départ (généralement la racine).
- Le membre récursif rattache le CTE à la table de base pour trouver le niveau suivant.
- Ajoutez une colonne depth pour suivre le nombre de niveaux parcourus par chaque nœud.
- Construisez une chaîne path pour générer des fils d’Ariane.
- Parcourez vers le haut en suivant parent_id en sens inverse afin de trouver tous les ancêtres.
- Utilisez un tableau visited pour vous protéger contre les cycles dans des données incohérentes.
Questions Fréquemment Posées
La leçon « Parcourir un arbre de catégories » est-elle gratuite ?
Oui — le texte complet de « Parcourir un arbre de catégories » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours SQL Academy, passe à CoddyKit PRO. Le cours SQL Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Parcourir un arbre de catégories » ?
Développez entièrement les arbres parent-enfant. Tu pratiques SQL Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer SQL Academy ?
Aucune expérience préalable n'est requise. SQL Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Parcourir un arbre de catégories » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon SQL Academy ?
Oui. Chaque leçon SQL Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Fonctionnement des CTE récursives
- Parcourir un arbre de catégories
- Générer des séries et des séquences
- Éviter les boucles infinies