Oracle分层查询:如何包含顶级父级

chr*_*ris 2 oracle hierarchical-data

我有一个分层查询来跟踪报告结构.这几乎是有效的,除了它没有报告顶级节点,可能是因为顶层人员"报告"自己.

查询是:

select
  level,
  empid, 
  parentid
from usertable
connect by nocycle prior parentid= empid
start with empid = 50
Run Code Online (Sandbox Code Playgroud)

这会产生:

LEVEL  EMPID PARENTID               
------ ----- --------  
1      50    258            
2      258   9555
3      9555  17839
Run Code Online (Sandbox Code Playgroud)

我没有达到4级,因为它看起来像:

4      17839 17839
Run Code Online (Sandbox Code Playgroud)

在不更改数据的情况下,有没有办法修改我的查询以便返回所有4个级别?目标是获得empid,所以我可以检查

id in (hierarchical subquery)

顺便说一句,如果我从查询中删除nocycle我得到一个错误.

Rob*_*ijk 5

克里斯,

您只获得3行,因为您的顶级行未按照处理分层查询的方式设置.通常,甲骨文着名的EMP表中的顶级行或总统KING没有经理.在你的情况下,你不应该将17389的parentid设置为17389本身,而是设置为NULL.要么相应地更新表,要么使用视图来适应这种情况.

一个例子:

SQL> select empno
  2       , mgr
  3    from emp
  4   where empno in (7876,7788,7566,7839)
  5  /

     EMPNO        MGR
---------- ----------
      7566       7839
      7788       7566
      7839       7839
      7876       7788

4 rijen zijn geselecteerd.
Run Code Online (Sandbox Code Playgroud)

EMP表的这一部分有四个级别,其顶级行(7839)设置为自身.与您的empid 17839相同.这导致您的查询只有三行:

SQL>  select level
  2        , empno
  3        , mgr
  4     from emp
  5  connect by nocycle prior mgr = empno
  6    start with empno = 7876
  7  /

     LEVEL      EMPNO        MGR
---------- ---------- ----------
         1       7876       7788
         2       7788       7566
         3       7566       7839

3 rijen zijn geselecteerd.
Run Code Online (Sandbox Code Playgroud)

使用(内联)视图将顶级的mgr/parentid列设置为null:

SQL>  select level
  2        , empno
  3        , mgr
  4     from ( select empno
  5                 , nullif(mgr,empno) mgr
  6              from emp
  7          )
  8  connect by nocycle prior mgr = empno
  9    start with empno = 7876
 10  /

     LEVEL      EMPNO        MGR
---------- ---------- ----------
         1       7876       7788
         2       7788       7566
         3       7566       7839
         4       7839

4 rijen zijn geselecteerd.
Run Code Online (Sandbox Code Playgroud)

或者使用UPDATE语句修复数据:

SQL> update emp
  2     set mgr = null
  3   where empno = 7839
  4  /

1 rij is bijgewerkt.

SQL>  select level
  2        , empno
  3        , mgr
  4     from emp
  5  connect by nocycle prior mgr = empno
  6    start with empno = 7876
  7  /

     LEVEL      EMPNO        MGR
---------- ---------- ----------
         1       7876       7788
         2       7788       7566
         3       7566       7839
         4       7839

4 rijen zijn geselecteerd.
Run Code Online (Sandbox Code Playgroud)

完成修复后,您也可以省略NOCYCLE关键字.

问候,Rob.