从单个表oracle中查找分层或父子列值

时间:2015-06-23 04:33:23

标签: sql oracle parent-child hierarchical-query

我有一个表名,它有两列,一列是 p ,第二列是 ch

else:

我想要的输出是父母的所有链接子。如果我给" 1"作为输入,我必须找到所有父元素和子元素,例如,在这种情况下,1是2,3,4的父级,2是5的父级,依此类推...在这种情况下,我需要每个链接的子元素和父母本身如下所述:

print

下面是我写的查询,我想确认它是最好的解决方案,或者我们可以做得更好,因为我的表中有大量数据:

p       ch 
-------------
1       2                   
1       3 
1       4 
2       5 
2       6 
7       8 
9       10 
11      12 
6       13 
13      14 
14      15 
14      16

2 个答案:

答案 0 :(得分:4)

使用分层查询:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE TREE ( p, ch ) AS
          SELECT  1,  2 FROM DUAL
UNION ALL SELECT  1,  3 FROM DUAL
UNION ALL SELECT  1,  4 FROM DUAL
UNION ALL SELECT  2,  5 FROM DUAL
UNION ALL SELECT  2,  6 FROM DUAL
UNION ALL SELECT  7,  8 FROM DUAL
UNION ALL SELECT  9, 10 FROM DUAL
UNION ALL SELECT 11, 12 FROM DUAL
UNION ALL SELECT  6, 13 FROM DUAL
UNION ALL SELECT 13, 14 FROM DUAL
UNION ALL SELECT 14, 15 FROM DUAL
UNION ALL SELECT 14, 16 FROM DUAL
UNION ALL SELECT  2,  1 FROM DUAL;

查询1

SELECT     p AS ParentChilds
FROM       TREE
START WITH p = 1
CONNECT BY NOCYCLE PRIOR ch = p
UNION
SELECT     ch
FROM       TREE
START WITH p = 1
CONNECT BY NOCYCLE PRIOR ch = p
UNION
SELECT     p
FROM       TREE
START WITH p = 1
CONNECT BY NOCYCLE ch = PRIOR p

<强> Results

| PARENTCHILDS |
|--------------|
|            1 |
|            2 |
|            3 |
|            4 |
|            5 |
|            6 |
|           13 |
|           14 |
|           15 |
|           16 |

查询2

SELECT     p AS ParentChilds
FROM       TREE
START WITH p = 6
CONNECT BY NOCYCLE PRIOR ch = p
UNION
SELECT     ch
FROM       TREE
START WITH p = 6
CONNECT BY NOCYCLE PRIOR ch = p
UNION
SELECT     p
FROM       TREE
START WITH p = 6
CONNECT BY NOCYCLE ch = PRIOR p

<强> Results

| PARENTCHILDS |
|--------------|
|            1 |
|            2 |
|            6 |
|           13 |
|           14 |
|           15 |
|           16 |

答案 1 :(得分:1)

这种方法可能稍微容易阅读,因为它使用更传统的递归cte方法,从根开始并将每个父级连接到其子级。根节点被标识为那些本身没有父节点的节点(where not exists)。

with LinkedAccounts(topRoot, parent, child, lvl)
as 
    (
        select r.p as topRoot, r.p as parent, r.ch as child, 1 as lvl
            from tree r
            where not exists
            (
                select 1 from tree t where r.p = t.ch
            )

        union all

        select la.topRoot
            , ch.p
            , ch.ch
            , la.lvl + 1
        from LinkedAccounts la
            inner join tree ch
            on ch.p = la.child
    ),
    ParentAndChild as
    (
        select topRoot, parent as node, lvl from LinkedAccounts

        union all

        select topRoot, child as node, lvl from LinkedAccounts
    )
    select distinct node
        from ParentAndChild
        where topRoot = 1
        order by node ASC;

SqlFiddle here

顺便说一下,层次结构中的命名约定是不寻常的 - ch通常是nodeid(但parent将是父/ parentid) - 这将模拟一个节点允许用于节点上的其他列。乍一看,您似乎正在建模连接关系本身,而不是节点?

相关问题