如何在给定树的节点的情况下找到整个树?
树的例子:
100
101 102
1010 1011 1020 1021
select level, employee_id, last_name, manager_id ,
connect_by_root employee_id as root_id
from employees
connect by prior employee_id = manager_id
start with employee_id = 101
;
表中的根是(父,子)示例(100,101)表中没有(null,100)行。
上面的查询只给出了从101开始的孩子。但是,让我说我想要从根开始的所有内容?
当给定'101'作为节点时,您将不知道哪个是根。
当root是给定节点时,查询应该可用。
答案 0 :(得分:7)
您需要首先遍历树,然后让所有经理走下去取得所有员工:
select level, employee_id, last_name, manager_id ,
connect_by_root employee_id as root_id
from employees
connect by prior employee_id = manager_id -- down the tree
start with manager_id in ( -- list up the tree
select manager_id
from employees
connect by employee_id = prior manager_id -- up the tree
start with employee_id = 101
)
;
请参阅http://www.sqlfiddle.com/#!4/d15e7/18
如果给定节点也可能是根节点,请扩展查询以在父节点列表中包含给定节点:
非根节点的示例:
select distinct employee_id, last_name, manager_id
from employees
connect by prior employee_id = manager_id -- down the tree
start with manager_id in ( -- list up the tree
select manager_id
from employees
connect by employee_id = prior manager_id -- up the tree
start with employee_id = 101
union
select manager_id -- in case we are the root node
from employees
where manager_id = 101
)
;
根节点示例:
select distinct employee_id, last_name, manager_id
from employees
connect by prior employee_id = manager_id -- down the tree
start with manager_id in ( -- list up the tree
select manager_id
from employees
connect by employee_id = prior manager_id -- up the tree
start with employee_id = 100
union
select manager_id -- in case we are the root node
from employees
where manager_id = 100
)
;
处小提琴
答案 1 :(得分:6)
为什么不呢:
select level, employee_id, last_name, manager_id ,
connect_by_root manager_id as root_id
from employees
connect by prior employee_id = manager_id
start with manager_id = 100
Here是一个小提琴
修改强>
这是另一个尝试(在了解完整问题之后):
with t as (
select case when mgr.employee_id is null then
1 else 0 end is_root, emp.employee_id employee, emp.manager_id manager, emp.last_name last_name
from employees mgr right outer join employees emp
on mgr.employee_id = emp.manager_id
),
tmp as (
select level, employee, last_name, manager ,
connect_by_root manager as root_id,
manager||sys_connect_by_path(employee,
',') cbp
from t
connect by prior employee = manager
start with t.is_root =
1 )
select * from tmp
where tmp.root_id in (select root_id from tmp where employee= 101 or manager = 101)
我使用100
,101
和1010
进行了检查,结果很好
Here是一个小提琴
答案 2 :(得分:1)
select
level,
employee_id,
last_name, manager_id ,
connect_by_root employee_id as root_id
from employees
connect by prior employee_id = manager_id
start with employee_id in (
select employee_id from employees
where manager_id is null )