Oracle Connect BY仅返回顶级

时间:2016-07-18 16:24:51

标签: sql oracle

我正在尝试使用connect by

获取记录中最顶级的父级
Select distinct parent_box_id,box_id, 
LEVEL,
SYS_CONNECT_BY_PATH(box_id, '>') "lineage"

  FROM box_lineage lineage 
  where lineage.position = 1 
        START WITH   box_id='00112233   '
   CONNECT BY   box_id = PRIOR parent_box_id
      ORDER SIBLINGS BY box_id;

结果

    parent child level hierarchy
    123456  789456  3   >00112233>963258>789456
    789456  963258  2   >00112233>963258
    963258  00112233    1   >00112233

我想要的只是123456 789456 3 >00112233>963258>789456

我不知道最高级别是2,3,4,5,6

我尝试了and level >=3level 1,但我只获得了最低级别

我已经在这里阅读了其他答案但没有工作

4 个答案:

答案 0 :(得分:3)

AND CONNECT_BY_ISLEAF = 1添加到where子句。

答案 1 :(得分:2)

只是为了说明John Ashley的正确答案,这里是针对HR模式中的EMPLOYEES表的类似查询(几乎存在于所有Oracle安装中)。

注意 - 所有的功劳都归功于John Ashley,我在这里只是说明他的解决方案。

select employee_id, manager_id, level, sys_connect_by_path(employee_id, '?') as path
from employees
where connect_by_isleaf = 1
start with employee_id = 116
connect by prior manager_id = employee_id
;

EMPLOYEE_ID MANAGER_ID      LEVEL PATH
----------- ---------- ---------- ---------------
        100                     3 ?116?114?100

(注意:在HR的EMPLOYEES表中," top"为NULL,公司CEO的MANAGER_ID - 这就是" parent"列显示NULL的原因。 )

答案 2 :(得分:1)

尝试使用级别

Select distinct parent_box_id,box_id, 
LEVEL,
SYS_CONNECT_BY_PATH(box_id, '>') "lineage"

  FROM box_lineage lineage 
  where lineage.position = 1 
  and level = 3
  CONNECT BY   box_id = PRIOR parent_box_id
  START WITH   box_id ='00112233   '
  ORDER SIBLINGS BY box_id;

.. for max try this

  Select distinct parent_box_id,box_id, 
  LEVEL,
  SYS_CONNECT_BY_PATH(box_id, '>') "lineage"

  FROM box_lineage lineage 
  where lineage.position = 1 
  and level =  (   

      Select max( LEVEL) 
      FROM box_lineage lineage 
      where lineage.position = 1
      CONNECT BY   box_id = PRIOR parent_box_id
      START WITH   box_id ='00112233   '

  )
  CONNECT BY   box_id = PRIOR parent_box_id
  START WITH   box_id ='00112233   '
  ORDER SIBLINGS BY box_id;

答案 3 :(得分:0)

如果我正确理解了这个问题,这就是我所做的:

使用普通员工示例可以做到这一点:

SELECT *
FROM
  ( SELECT DISTINCT lowest_employee_id as employee_id,
    manager_id,
    l AS path_level,
    path,
    rank() over (partition BY lowest_employee_id order by l DESC) rnk
  FROM
    (
SELECT employee_id ,
      manager_id,
      level l,
      -- the following line is just for visualization purpose
      SYS_CONNECT_BY_PATH(manager_id, ' > ') path,
      connect_by_root(employee_id ) lowest_employee_id
    from employees
    start with employee_id = 116
    connect by prior manager_id = employee_id
    )
  )
WHERE rnk = 1

说明:

connect_by_root将存储每个级别的起始根,然后我们根据级别编号对其进行排名,然后仅过滤最新的