簡體   English   中英

從根節點找到整個樹,給出任何節點

[英]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
     )
;

小提琴在http://www.sqlfiddle.com/#!4/d15e7/32

為什么不呢:

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)

我檢查了1001011010 ,效果不錯
是一個小提琴

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM