5

ツリーのノードを指定してツリー全体を見つけるにはどうすればよいですか?

ツリーの例:

       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」を指定すると、どれがルートかわかりません。

ルートが指定されたノードである場合、クエリを使用できる必要があります。

4

3 に答える 3

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
     )
;

http://www.sqlfiddle.com/#!4/d15e7/32のフィドル

于 2012-07-24T06:29:16.037 に答える
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

これがフィドルです

編集
ここに別の試みがあります(完全な問題を理解した後):

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

于 2012-07-24T05:36:17.990 に答える