2009-05-21 78 views
2

我有一个分层查询来跟踪报告结构。这几乎可以工作,除非它没有报告顶级节点,可能是因为顶级人员“自我报告”。Oracle分层查询:如何包含顶层父项

查询是:

select 
    level, 
    empid, 
    parentid 
from usertable 
connect by nocycle prior parentid= empid 
start with empid = 50 

这将产生:

LEVEL EMPID PARENTID    
------ ----- -------- 
1  50 258    
2  258 9555 
3  9555 17839 

我没有得到一个4级,因为它看起来像:

4  17839 17839 

不改变数据,有没有办法修改我的查询,以便返回所有4个级别?我们的目标是让empids,这样我就可以为

id in (hierarchical subquery)

做一次检查顺便说一句,如果我从查询中删除我得到一个错误的NOCYCLE。

回答

5

克里斯,

你只得到3行,因为你的顶层行不设置应该的方式来处理层次查询。通常情况下,顶级行或Oracle着名的EMP表中的总裁KING都没有经理。在你的情况下,你不应该把17389的参数设置为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. 

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. 

要么使用一个(内联)视图设置经理/ parentId的列设置为空的顶级:

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. 

或修复您的数据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. 

而且你可以离开了NOCYCLE关键字以及,你做固定后。

Regards, Rob。

3

您需要以相反的方式执行层次结构,从根到叶。

select 
    level, 
    empid, 
    parentid 
from usertable 
start with empid = 17839 
connect by empid != 17839 and prior empid = parentid 

LEVEL     EMPID     PARENTID    
---------------------- ---------------------- ---------------------- 
1      17839     17839     
2      9555     17839     
3      258     9555     
4      50      258      

4 rows selected 
+0

不幸的是,这不起作用。 顶层将有一大堆的2级的,但我只希望在上述水平4.思考的员工,经理,总监,副总裁层次结构中的2级 - 导演和VP可以看到员工创建的数据,但另一向该董事报告的经理不能。 – chris 2009-05-21 14:42:17

0

好像你在数据的周期。如果没有“nocycle”,它将不会马上起作用。如果您知道所有数据的最大嵌套级别为4,则可以添加条件“和级别< = 4”并删除nocycle。应该管用。

+0

不幸的是,嵌套级别会有所不同。 – chris 2009-05-21 14:43:25

1

您不必更改结构。

只需使用下面的查询

select 
    level, 
    empid, 
    parentid 
from usertable 
connect by prior parentid = empid 
     AND parentid <> empid -- This line prohibits cycling and ALLOWS a row where parentid = empid 
start with empid = 50 
0

凡Heddegem Roeland的答案不适合我的工作,我已经试过了,但我已经成功地做到这一点没有一个内嵌视图,在连接子句中,通过添加: -

and prior empid <> parentid 

下面的文章解释了为什么这样的作品 - 如果你可以让你的头转过来!尽管一旦你“明白了”它确实是合乎逻辑的。 (这是与<>运营商的每一侧的计算顺序做。)

Oracle: Connect By Loop in user data

内联视图会工作,但不会对您的特定数据集的研究,我不知道什么样的影响内嵌视图可能在查询路径上。在大多数情况下,添加额外的子句可能是“正确的”方法,恕我直言。