Рекурсивные запросы выполняются с использованием рекурсивного common table expression в Postgres.
Вы можете имитировать Oracle level
, просто увеличивая значение для каждой итерации, а затем сравнивая это во внешнем запросе.
Лист можно проверить с помощью вложенного запроса - по аналогии с тем, что mt0 сделал
nocycle
можно сделать, помня все строки, которые были обработаны и добавление где условия рекурсивной части, которая останавливается, если сотрудник уже обработан.
Выполняя первоначальную EMP_ID через все уровни, вы можете также имитировать connect_by_root
with recursive cte (emp_id, mgr_id, name, path, level, visited, root_id) AS
(
select emp_id,
mgr_id,
name,
'/' || name,
1 as level,
array[emp_id] as visited,
emp_id as root_id
from employee e
where emp_id = 345
union all
select c.emp_id,
c.mgr_id,
c.name,
concat_ws('/', p.path, c.name),
p.level + 1,
p.visited || c.emp_id,
p.root_id
from employee c
join cte p on p.emp_id = c.mgr_id
where c.emp_id <> all(p.visited)
)
SELECT e.*,
not exists (select * from cte p where p.mgr_id = e.emp_id) as is_leaf
FROM cte e;
Online пример Оракула: http://rextester.com/TSMVV17478
Будет ли получить правильное значение листа, когда листья могут быть на разных глубинах в разные ветви дерева иерархии? – MT0
@ MT0: он может быть изменен, чтобы справиться с этим. Данный пример имеет только одну ветвь (из-за 'where emp_id = 345', поэтому я не включил это) –
Запрос идет вниз по дереву управления, поэтому возможно, что существует ветвь, которая является'/Manager/Team Lead/Worker' и другой филиал '/ Manager/Team Lead/Supervisor/Intern', ни Работник, ни Интернэшнл не управляют другими сотрудниками (так будет листья), но находятся на разных глубинах (и имеют один и тот же корень). – MT0