我有一个表名树,它有两列,一列是 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
答案 0 :(得分:4)
使用分层查询:
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;
顺便说一下,层次结构中的命名约定是不寻常的 - ch
通常是nodeid
(但parent
将是父/ parentid) - 这将模拟一个节点允许用于节点上的其他列。乍一看,您似乎正在建模连接关系本身,而不是节点?