Saltar al contenido principal
eLearner.app
Módulo 7 · Lección 4 de 428/57 en el curso~14 min
Lecciones del módulo (4/4)

CTEs recursivas: jerarquías de profundidad arbitraria

Una auto-UNIÓN (Módulo 5) encuentra sólo un nivel de una jerarquía: hijo → padre. Pero, ¿qué sucede si la jerarquía tiene 3, 5 o n niveles de profundidad? y no sabes de antemano cuantos? Necesitas CTE recursivos: a CTE que se refiere a sí mismo para "ampliar" los resultados de forma iterativa.

En el conjunto de datos ecommerce, la tabla categories tiene 3 raíces (Elettronica, Libri, Casa) y 2 niños cada uno: un árbol de 2 niveles. es un Caso simple pero suficiente para aprender el patrón.

La sintaxis

SQL
WITH RECURSIVE nome (col1, col2, …) AS (
  -- (1) Termine BASE: le righe di partenza
  SELECT
  FROM
  WHERE

  UNION ALL

  -- (2) Termine RICORSIVO: si appoggia a "nome" stesso per espandere
  SELECT
  FROM   tabella  t
  JOIN   nome    n  ON
)
SELECT * FROM nome;

Cómo funciona en la práctica:

  1. PostgreSQL ejecuta el término base una vez.
  2. Ejecuta el término recursivo usando las filas recién producidas como "entrada" (no todo el CTE: sólo el incremento).
  3. Repite el paso 2 hasta que el término recursivo produzca 0 filas nuevas.
  4. El resultado final es el UNION ALL de todos los pasos.

Ejemplo 1: árbol con profundidad y camino

SQL
WITH RECURSIVE tree AS (
  -- base: le radici (parent_id IS NULL)
  SELECT id,
         name,
         parent_id,
         1                 AS depth,
         name              AS path
  FROM   categories
  WHERE  parent_id IS NULL

  UNION ALL

  -- ricorsivo: per ogni categoria che ha come parent una riga già in tree
  SELECT c.id,
         c.name,
         c.parent_id,
         t.depth + 1,
         t.path || ' > ' || c.name
  FROM   categories c
  JOIN   tree       t ON c.parent_id = t.id
)
SELECT id, name, depth, path
FROM   tree
ORDER BY path;

La primera iteración produce 3 filas (las raíces en el nivel 1). el segundo la iteración encuentra a los 6 niños (nivel 2). La tercera iteración encuentra nada → hecho.

Ejemplo 2: dado un nodo, encontrar su raíz

Una variante "de arriba hacia abajo → de abajo hacia arriba": propagamos la identificación de la raíz hacia abajo a lo largo el árbol.

SQL
WITH RECURSIVE tree AS (
  SELECT id,
         name,
         parent_id,
         id   AS root_id,
         name AS root_name
  FROM   categories
  WHERE  parent_id IS NULL

  UNION ALL

  SELECT c.id,
         c.name,
         c.parent_id,
         t.root_id,    -- propago lo stesso id_radice
         t.root_name   -- e nome
  FROM   categories c
  JOIN   tree       t ON c.parent_id = t.id
)
SELECT id, name, root_name
FROM   tree
ORDER BY id;

Pruébalo

Ejercicio#sql.m7.l4.e1
Intentos: 0Cargando...

Utilice un CTE recursivo llamado "árbol" para aplanar la jerarquía de categorías. Muestra ID, nombre, profundidad (1 para raíces, 2 para niños, etc.) y ruta (por ejemplo, 'Elettronica > Audio'). Ordenar por ruta.

Cargando editor...
Mostrar pista

JOIN en el término recursivo vincula c.parent_id a la fila que ya está presente en el árbol (t.id).

Solución disponible después de 3 intentos

Ejercicio de revisión

Ejercicio#sql.m7.l4.e2
Intentos: 0Cargando...

Para cada categoría, muestre id, nombre y root_name (el nombre de la categoría raíz en la parte superior del árbol al que pertenece). Las raíces tienen nombre_raíz = nombre. Ordenar por id.

Cargando editor...
Mostrar pista

Propague nombre_raíz del padre (t.nombre_raíz) al hijo (c).

Solución disponible después de 3 intentos