Как в PostgreSQL выполняются рекурсивные запросы и в каких случаях они полезны?

Ответ

Да, PostgreSQL поддерживает рекурсивные запросы с помощью конструкции WITH RECURSIVE.

Они незаменимы для работы с иерархическими или графовыми структурами данных, такими как:

  • Организационная структура компании (менеджеры и подчиненные).
  • Дерево категорий в интернет-магазине.
  • Социальные связи (поиск друзей друзей).
  • Маршруты в транспортной сети.

Структура рекурсивного запроса

Запрос состоит из двух частей, объединенных через UNION ALL:

  1. Начальная (anchor) часть: Нерекурсивный SELECT, который выполняется один раз и формирует стартовый набор данных.
  2. Рекурсивная часть: SELECT, который ссылается на сам себя (на имя CTE) и выполняется до тех пор, пока возвращает непустой результат.

Пример: поиск всех подчиненных для заданного руководителя

WITH RECURSIVE subordinates AS (
    -- 1. Начальная часть: находим прямых подчиненных руководителя с id = 1
    SELECT id, name, manager_id
    FROM employees
    WHERE manager_id = 1

    UNION ALL

    -- 2. Рекурсивная часть: присоединяем сотрудников, чей manager_id
    --    совпадает с id сотрудника из предыдущего шага
    SELECT e.id, e.name, e.manager_id
    FROM employees e
    INNER JOIN subordinates s ON s.id = e.manager_id
)
SELECT * FROM subordinates;

Важные моменты:

  • Условие завершения: Рекурсия прекращается, когда рекурсивная часть перестает возвращать новые строки. Крайне важно правильно составить условие объединения, чтобы избежать бесконечного цикла.
  • Производительность: На очень глубоких или широких иерархиях рекурсивные запросы могут быть медленными. В таких случаях стоит рассмотреть альтернативные способы хранения иерархии (например, ltree или Materialized Path).