Ответ
Основное различие в том, что нерекурсивное CTE — это просто временный, именованный набор результатов для упрощения сложных запросов, а рекурсивное CTE ссылается на само себя для выполнения итеративных операций, что идеально подходит для работы с иерархическими или графовыми данными.
Нерекурсивное CTE
Используется как временная таблица в рамках одного запроса. Улучшает читаемость.
Пример: выбрать активных пользователей и затем отфильтровать их по имени.
WITH ActiveUsers AS (
SELECT id, name, email
FROM users
WHERE status = 'active'
)
SELECT name, email
FROM ActiveUsers
WHERE name LIKE 'A%';
Рекурсивное CTE
Имеет обязательную структуру из двух частей, объединенных UNION ALL
:
- Базовый случай (Anchor Member): Начальный запрос, который выполняется один раз.
- Рекурсивная часть (Recursive Member): Запрос, который ссылается на само CTE и выполняется до тех пор, пока не вернет пустой результат.
Пример: найти иерархию категорий товаров.
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;
В Go для выполнения таких запросов используется стандартный пакет database/sql
, а результат обрабатывается как обычный SELECT
.