Есть два сложных момента о рекурсивном синтаксисе WITH.
Мы определяем два запроса, один из которых является якорем (значение START WITH) с UNION ALL на втором запросе, который извлекает дочерние элементы иерархического.
Другая проблема заключается в том, что мы не можем использовать LEVEL для создания заполнения в запросе CONNECT BY (потому что мы не используем CONNECT BY). Поэтому мы добавляем еще один столбец, чтобы поддерживать подсчет уровней при навигации по дереву. Обратите внимание, что я начал с нуля, так что вершина иерархии не дополняется звездочками.
Итак, вот ваш запрос повторно отливают в виде рекурсивной С утверждением:
with e1 (ename, empno, lvl)
as (select ename
, empno
, 0 as lvl
from emp
where mgr is null
union all
select e2.ename
, e2.empno
, e1.lvl + 1
from emp e2, e1
where e2.mgr = e1.empno)
search depth first by empno set empno_order
select rpad ('*', 2 * e1.lvl, '*') || e1.ename ename
, e1.empno
from e1
order by empno_order
;
Предложение search depth first
гарантирует набор результатов показывает все дети данного узла перед отображением узла родственный. (search breadth first
перечислит всех братьев и сестер, затем начните на следующем уровне иерархии.)
Теперь, чтобы сделать обратную прогулку по дереву, нам нужно начать с сотрудников, которые не являются менеджерами. Поскольку мы проверяем нули, нам нужно использовать NOT EXISTS, а не NOT IN. В противном случае запрос будет почти таким же; Я решил показать MGR, а не EMPNO, но вы можете предпочесть вернуться.
with e1 (ename, mgr, lvl)
as (select e.ename
, e.mgr
, 0 as lvl
from emp e
where not exists (select null
from emp x
where x.mgr = e.empno)
union all
select e2.ename
, e2.mgr
, e1.lvl + 1
from emp e2, e1
where e2.empno = e1.mgr)
search depth first by mgr set mgr_order
select rpad ('*', 2 * e1.lvl, '*') || e1.ename ename
, e1.mgr
from e1
order by mgr_order
;
Вот пример вывода из этого запроса:
ENAME MGR
------------------------------ ----------
ALLEN 7698
**BLAKE 7839
****KING
JAMES 7698
**BLAKE 7839
****KING
MARTIN 7698
**BLAKE 7839
****KING
TURNER 7698
...
Я не уверен, я понимаю, что вы хотите, но вы пытаетесь CONNECT BY ПРИОР прил = EMPNO, и, возможно, изменить начало с выражением на подходящем? –