sql—获取整个层次结构的递归查询[oracle]

pepwfjgg  于 2021-08-09  发布在  Java
关注(0)|答案(1)|浏览(390)

我不熟悉递归查询,所以如果这是一个简单的解决方案,我很抱歉,但我想这会有点困难。
我得到了一个层次结构表,它定义了多个级别的父子关系,我需要一种方法来显示一个项可以具有的所有可能的关系。还有一些循环关系我无法摆脱-我不确定这是否会导致问题。
例如,原始数据如下所示:

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

到目前为止,我的方法是根据需要多次将表连接回自身,直到定义了整个关系(即,原始父级/pn的每个子级/int),但我希望有更好的方法使用递归查询。
希望这是有意义的,并提前感谢!

dojqjjoe

dojqjjoe1#

为每一行构建层次结构,返回 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 子句检测循环。

相关问题