В чем разница между рекурсивным и нерекурсивным CTE (Common Table Expression)?

Ответ

Основное различие в том, что нерекурсивное 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:

  1. Базовый случай (Anchor Member): Начальный запрос, который выполняется один раз.
  2. Рекурсивная часть (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.