2008-09-22 43 views
8

给出一个简单的(ID,描述)表t1,如在Oracle树加入其他表的查询

id description 
-- ----------- 
1 Alice 
2 Bob 
3 Carol 
4 David 
5 Erica 
6 Fred 

而且父子关系表T2,如

parent child 
------ ----- 
1  2 
1  3 
4  5 
5  6 

Oracle提供一种将其作为具有一些自定义语法扩展的树遍历的方式:

select parent, child, sys_connect_by_path(child, '/') as "path" 
from t2 
connect by prior parent = child 

确切的语法并不重要,我在上面可能犯了一个错误。该 重要的是,上面会产生一些看起来像

parent child path 
------ ----- ---- 
1  2  /1/2 
1  3  /1/3 
4  5  /4/5 
4  6  /4/5/6 
5  6  /5/6 

我的问题是:是否有可能加入SYS_CONNECT_BY_PATH()内的另一个表,如表T1以上,产生类似:

parent child path 
------ ----- ---- 
1  2  /Alice/Bob 
1  3  /Alice/Carol 
... and so on... 

回答

7

在您的查询中,将T2替换为连接T1和T2的子查询,并返回父,子和子描述。然后在sys_connect_by_path函数中,引用子查询中的子描述。

+0

换句话说,使用派生表。当然!好戏。 – dland 2008-09-23 07:57:09

0
SELECT parent, child, parents.description||sys_connect_by_path(childs.description, '/') AS "path" 
FROM T1 parents, T1 childs, T2 
WHERE T2.parent = parents.id 
AND T2.child = childs.id 
CONNECT BY PRIOR parent = child 
+0

这不起作用。在多级别层次结构中,路径不正确。 比如David/Fred/Erica而不是David/Erica/Fred – dland 2008-09-23 07:37:20

6

基于迈克·麦卡利斯特的想法,下面使用派生表,以达到预期的效果:

select 
    T.PARENT 
    ,T.CHILD 
    ,sys_connect_by_path(T.CDESC, '/') 
from 
    (
     select 
      t2.parent  as PARENT 
      ,t2.child  as CHILD 
      ,t1.description as CDESC 
     from 
      t1, t2 
     where 
      t2.child = t1.id 
    ) T 
where 
    level > 1 and connect_by_isleaf = 1 
connect by prior 
    T.CHILD = T.PARENT 

在我的问题,所有的家长都在“超级父母”根锚定,这意味着路径可以用SYS_CONNECT_BY_PATH完全描述,从而避免了需要将cagcowboy的父级与路径连接起来的技术。

+1

好东西,谢谢你把你的解决方案放在这里。我希望更多的人会这样做,这有助于下一个来StackOverflow寻找答案的人。 – 2008-09-23 12:39:00