鉴于以下模型:
create table child_parent (
child number(3),
parent number(3)
);
鉴于以下数据:
insert into child_parent values(2,1);
insert into child_parent values(3,1);
insert into child_parent values(4,2);
insert into child_parent values(5,2);
insert into child_parent values(6,3);
产生以下树:
1
/ \
2 3
/ \ \
4 5 6
现在我可以找到5的父母:
SELECT parent FROM child_parent START WITH child = 5
CONNECT BY NOCYCLE PRIOR parent = child;
但是如何从5开始获取所有节点(1,2,3,4,5,6)?
答案 0 :(得分:2)
最后,我提出了类似这样的解决方案:
SELECT child FROM child_parent START WITH parent =
(
SELECT DISTINCT parent FROM
(
SELECT parent
FROM child_parent
WHERE CONNECT_BY_ISLEAF = 1
START WITH child = 5
CONNECT BY PRIOR parent = child
UNION
SELECT parent
FROM child_parent
WHERE parent = 5
)
)
CONNECT BY NOCYCLE PRIOR child = parent
UNION
SELECT DISTINCT parent FROM
(
SELECT parent
FROM child_parent
WHERE CONNECT_BY_ISLEAF = 1
START WITH child = 5
CONNECT BY PRIOR parent = child
UNION
SELECT parent
FROM child_parent
WHERE parent = 5
);
它适用于所提供示例的所有节点。 但是,如果其中一个叶子具有第二个父节点,并且起始点位于此节点之上或位于不同分支中,则它不起作用。
但对我来说这已经足够了。
获取图中所有节点的解决方案可以是: 实现与上面查询相反的(从上到下),然后执行它们(从下到上,从上到下),反之亦然,直到找不到更多新节点。 这需要PL / SQL,我也不知道性能。
答案 1 :(得分:1)
使用5你不能遍历整棵树,即使你可以实现它也会非常棘手,因为它是一个叶元素。
尝试以下查询,它将遍历整个树,但您必须从root而不是leaf开始:
select * from (
SELECT child FROM child_parent START WITH parent = 1
CONNECT BY NOCYCLE PRIOR child = parent
union
select 1 from dual)
order by child;
您可以将“1”替换为任何其他根元素,将打印该根目录下的所有元素,包括该根。
答案 2 :(得分:1)
Oracle的CONNECT BY语法用于遍历分层数据:它是单向的,因此不适合表示图形,这需要双向性。在一个查询中无法转到2 -> 1 -> 3
,这是您从5开始获取所有节点所需要做的。
很久以前我回答了关于在层次结构中展平节点的问题(AKA传递闭包),即如果1->2->3
为真,则“1> 3”也是如此。它链接到一篇论文,该论文演示了PL / SQL解决方案,以生成所有边并将它们存储在表中。在这种情况下可以使用类似的解决方案。但显然,如果图中的节点不经常使用,那么它才是实用的。所以也许它的用途有限。无论如何,find out more。