Собесов

Glassdoor (Microsoft) — иерархия сотрудник→менеджер через рекурсивный CTE

SQLИерархииСложнаяSenior

Условие

Таблица employees(employee_id, name, manager_id) — у каждого сотрудника один менеджер (или NULL для CEO). Для каждого сотрудника верните полную цепочку менеджеров (от прямого руководителя до CEO) в виде строки через .

Решение

Рекурсивный CTE

WITH RECURSIVE chain AS (
  SELECT
    employee_id, name, manager_id,
    name::TEXT AS path,
    1 AS depth
  FROM employees
 
  UNION ALL
 
  SELECT
    e.employee_id, e.name, m.manager_id,
    c.path || ' → ' || m.name,
    c.depth + 1
  FROM chain c
  JOIN employees m ON m.employee_id = c.manager_id
  JOIN employees e ON e.employee_id = c.employee_id
)
SELECT employee_id, name, path AS manager_chain
FROM chain
WHERE manager_id IS NULL  -- остановились на CEO
ORDER BY employee_id;

Объяснение

  • Базовый кейс: каждый сотрудник — стартовая точка, path = name.
  • Рекурсия: переходим к менеджеру, добавляем его в путь.
  • Останов: когда manager_id IS NULL — добрались до CEO.

Защита от циклов

Если в данных есть зацикленность (A — менеджер B, B — менеджер A), рекурсия уйдёт в бесконечность. Postgres имеет CYCLE clause (с 14):

WITH RECURSIVE chain AS (...)
CYCLE employee_id SET is_cycle USING path_arr

В MySQL и старом Postgres — ограничивать через depth < 100.

Подводные камни

  1. Базовый кейс не для CEO. Стартуем со ВСЕХ сотрудников, не с CEO — иначе сложно собрать путь «снизу вверх».
  2. UNION vs UNION ALL. Только UNION ALL — иначе оптимизатор может схлопнуть строки.
  3. Сборка пути в обратном порядке. Здесь конкатенируем c.path || ' → ' || m.name — путь идёт от сотрудника вверх. Если просят сверху вниз — собирать иначе или строить массив и реверсить.
  4. Производительность. Рекурсивные CTE плохо масштабируются на больших иерархиях. На 1М сотрудников — не вариант, делать MATERIALIZED hierarchy table.

Эталонный ответ

WITH RECURSIVE, базовый = все, шаг = JOIN с менеджером, останов по manager_id IS NULL. Конкатенация строки или массива по пути.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти