递归查询以获取整个层次结构 [ORACLE]
Recursive query to get entire hierarchy [ORACLE]
我是递归查询的新手,如果这是一个简单的解决方案,我深表歉意,但我认为它会有点难。
我得到了一个层次结构 table,其中定义了多个级别的父子关系,我需要一种方法来显示一个项目可能具有的所有可能关系。还有一些我无法摆脱的循环关系 - 我不确定这是否会导致问题。
例如,原始数据如下所示:
PN INT
===== =====
ABC1 ABC2
ABC1 ABC9
ABC2 ABC3
ABC3 ABC4
DEF1 DEF2
GHI1 GHI2
GHI2 GHI1
我需要查询结果如下所示:
PN INT
===== =====
ABC1 ABC2
ABC1 ABC9
ABC1 ABC3
ABC1 ABC4
ABC2 ABC3
ABC2 ABC4
ABC3 ABC4
DEF1 DEF2
GHI1 GHI2
GHI2 GHI1
到目前为止,我的方法是根据需要多次将 table 重新加入自身,直到我定义了整个关系(即原始 [=25= 的每个 child/INT ]) 但我希望有更好的方法使用递归查询。
希望这是有道理的,提前致谢!
为每一行构建层次结构,为根行返回 pn
的值。
您可以使用 connect by
使用 connect_by_root
:
create table t (
c1 varchar2(4), c2 varchar2(4)
);
insert into t values ( 'ABC1', 'ABC2' );
insert into t values ( 'ABC1', 'ABC9' );
insert into t values ( 'ABC2', 'ABC3' );
insert into t values ( 'ABC3', 'ABC4' );
insert into t values ( 'DEF1', 'DEF2' );
insert into t values ( 'GHI1', 'GHI2' );
insert into t values ( 'GHI2', 'GHI1' );
commit;
select * from (
select distinct connect_by_root c1 rt, c2
from t
connect by nocycle c1 = prior c2
)
where rt <> c2
order by rt, c2;
RT C2
ABC1 ABC2
ABC1 ABC3
ABC1 ABC4
ABC1 ABC9
ABC2 ABC3
ABC2 ABC4
ABC3 ABC4
DEF1 DEF2
GHI1 GHI2
GHI2 GHI1
nocycle
子句检测循环并停止处理。
或通过在每次迭代中选择根的值递归with
:
with tree ( c1, c2, rt ) as (
select c1, c2, c1 from t
union all
select t.c1, t.c2, tree.rt
from tree
join t
on t.c1 = tree.c2
) cycle c1 set is_cycle to 'Y' default 'N'
select rt, c2
from tree
where is_cycle = 'N'
and rt <> c2
order by rt, c2;
RT C2
ABC1 ABC2
ABC1 ABC3
ABC1 ABC4
ABC1 ABC9
ABC2 ABC3
ABC2 ABC4
ABC3 ABC4
DEF1 DEF2
GHI1 GHI2
GHI2 GHI1
cycle
子句检测循环。
我是递归查询的新手,如果这是一个简单的解决方案,我深表歉意,但我认为它会有点难。
我得到了一个层次结构 table,其中定义了多个级别的父子关系,我需要一种方法来显示一个项目可能具有的所有可能关系。还有一些我无法摆脱的循环关系 - 我不确定这是否会导致问题。
例如,原始数据如下所示:
PN INT
===== =====
ABC1 ABC2
ABC1 ABC9
ABC2 ABC3
ABC3 ABC4
DEF1 DEF2
GHI1 GHI2
GHI2 GHI1
我需要查询结果如下所示:
PN INT
===== =====
ABC1 ABC2
ABC1 ABC9
ABC1 ABC3
ABC1 ABC4
ABC2 ABC3
ABC2 ABC4
ABC3 ABC4
DEF1 DEF2
GHI1 GHI2
GHI2 GHI1
到目前为止,我的方法是根据需要多次将 table 重新加入自身,直到我定义了整个关系(即原始 [=25= 的每个 child/INT ]) 但我希望有更好的方法使用递归查询。
希望这是有道理的,提前致谢!
为每一行构建层次结构,为根行返回 pn
的值。
您可以使用 connect by
使用 connect_by_root
:
create table t (
c1 varchar2(4), c2 varchar2(4)
);
insert into t values ( 'ABC1', 'ABC2' );
insert into t values ( 'ABC1', 'ABC9' );
insert into t values ( 'ABC2', 'ABC3' );
insert into t values ( 'ABC3', 'ABC4' );
insert into t values ( 'DEF1', 'DEF2' );
insert into t values ( 'GHI1', 'GHI2' );
insert into t values ( 'GHI2', 'GHI1' );
commit;
select * from (
select distinct connect_by_root c1 rt, c2
from t
connect by nocycle c1 = prior c2
)
where rt <> c2
order by rt, c2;
RT C2
ABC1 ABC2
ABC1 ABC3
ABC1 ABC4
ABC1 ABC9
ABC2 ABC3
ABC2 ABC4
ABC3 ABC4
DEF1 DEF2
GHI1 GHI2
GHI2 GHI1
nocycle
子句检测循环并停止处理。
或通过在每次迭代中选择根的值递归with
:
with tree ( c1, c2, rt ) as (
select c1, c2, c1 from t
union all
select t.c1, t.c2, tree.rt
from tree
join t
on t.c1 = tree.c2
) cycle c1 set is_cycle to 'Y' default 'N'
select rt, c2
from tree
where is_cycle = 'N'
and rt <> c2
order by rt, c2;
RT C2
ABC1 ABC2
ABC1 ABC3
ABC1 ABC4
ABC1 ABC9
ABC2 ABC3
ABC2 ABC4
ABC3 ABC4
DEF1 DEF2
GHI1 GHI2
GHI2 GHI1
cycle
子句检测循环。