Oracle分层查询沿路径选择记录

时间:2015-10-06 07:21:37

标签: sql oracle hierarchical-data recursive-query

假设公司层次结构如下:

King
-> John
  -> Jack
    -> Chris
    -> Sean
  -> April
-> Jerry
  -> Tom

鉴于祖先,例如Kingsubordinate,例如Chris,是否可以在一个查询中选择路径/King/John/Jack/Chris中的所有记录?即查询将返回4条记录 - King, John, Jack and Chris

表格结构: Employee_Name Employee_ID Manager_ID

Manager_ID引用Employee_ID

2 个答案:

答案 0 :(得分:0)

with t as
(
    select 'King' as Employee_Name,  1 as Employee_ID, -1 as Manager_ID from dual union all
    select 'John' as Employee_Name,  2 as Employee_ID, 1 as Manager_ID from dual union all
    select 'Jack' as Employee_Name,  3 as Employee_ID, 2 as Manager_ID from dual union all
    select 'Chris' as Employee_Name, 4  as Employee_ID, 3 as Manager_ID from dual union all
    select 'Sean' as Employee_Name,  5 as Employee_ID, 3 as Manager_ID from dual union all
    select 'April' as Employee_Name,  6 as Employee_ID, 2 as Manager_ID from dual union all
    select 'Jerry' as Employee_Name, 7  as Employee_ID, 1 as Manager_ID from dual union all
    select 'Tom' as Employee_Name, 8  as Employee_ID, 7 as Manager_ID from dual
)
select Employee_Name 
 from t
connect by prior Manager_ID = Employee_ID
start with Employee_Name = 'Chris'
order by level desc

答案 1 :(得分:0)

我不确定你的桌面结构是什么。如果您将其存储为路径,则以下内容应该有效。该查询支持Chris的多个记录。它将选择所有这些。

with test as
  (
  select 1 id, '/King/John/Jack/Chris' str from dual union all
  select 2 id, '/King/John/Jack/April' str from dual union all
  select 3 id, '/King/John/Jack/Sean' str from dual union all
  select 4 id, '/King/Jerry/Tom' str from dual
)
   select id,
          str,
         regexp_substr (str, '[^/]+', 1, rn) split,
          rn
    from test 
    cross
    join (select rownum rn
            from (select max (length (regexp_replace (str, '[^/]+'))) + 1 mx
                    from test
                )
       connect by level <= mx
         ) A
   where regexp_substr (str, '[^/]+', 1, rn) is not null
    and instr(str, 'Chris') > 0 
   order by id, rn
 ;

以下是SQL Fiddle

中的一个示例

Example in SQL Fiddle

技巧是交叉连接,为主表中的每一行创建多行。

ID  STR SPLIT   RN
1   /King/John/Jack/Chris   King    1
1   /King/John/Jack/Chris   John    2
1   /King/John/Jack/Chris   Jack    3
1   /King/John/Jack/Chris   Chris   4