![](/img/trans.png)
[英]Oracle SQL: How to get the nth node between the root and any node in a tree (Optimizing)
[英]Find the entire tree from the root giving any node
如何在給定樹的節點的情況下找到整個樹?
樹的例子:
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'作為節點時,您將不知道哪個是根。
當根是給定節點時,查詢應該可用。
您需要首先遍歷樹以使所有經理然后遍歷以獲取所有員工:
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
)
;
為什么不呢:
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
這是一個小提琴
編輯
這是另一個嘗試(在了解完整問題之后):
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
,效果不錯
這是一個小提琴
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 )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.