Ответ
Рекурсивные CTE (Common Table Expressions или обобщенные табличные выражения) — это мощный инструмент в SQL, который позволяет выполнять запросы к иерархическим или графовым структурам данных.
По сути, это CTE, которое ссылается само на себя. Оно состоит из двух обязательных частей:
- Базовая (якорная) часть (Anchor Member): Начальный запрос, который выполняется один раз и формирует стартовый набор данных. Это условие выхода из рекурсии.
- Рекурсивная часть (Recursive Member): Запрос, который ссылается на CTE и выполняется многократно, на каждой итерации добавляя новые строки к результату предыдущей, пока не перестанет возвращать новые данные.
Эти две части объединяются с помощью UNION ALL
.
Основное применение — работа с иерархиями: организационные структуры, деревья категорий, связи в социальных сетях, маршруты на карте.
Пример: Получение дерева категорий
WITH RECURSIVE CategoryTree AS (
-- 1. Базовая часть: находим корневые категории (у которых нет родителя)
SELECT id, name, parent_id, 0 AS level
FROM categories
WHERE parent_id IS NULL
UNION ALL
-- 2. Рекурсивная часть: присоединяем дочерние категории к уже найденным
SELECT c.id, c.name, c.parent_id, ct.level + 1
FROM categories c
JOIN CategoryTree ct ON c.parent_id = ct.id
)
SELECT * FROM CategoryTree;
Ключевые моменты:
- В PostgreSQL и некоторых других СУБД обязательно ключевое слово
RECURSIVE
. - Использование
UNION ALL
предпочтительнееUNION
, так какUNION
удаляет дубликаты на каждом шаге, что сильно снижает производительность. - Важно спроектировать запрос так, чтобы рекурсия гарантированно завершилась, иначе можно получить бесконечный цикл.
- СУБД имеют встроенную защиту от бесконечной рекурсии (например,
max_recursion_depth
в PostgreSQL).