【问题标题】:Recursive query to get entire hierarchy [ORACLE]递归查询以获取整个层次结构 [ORACLE]
【发布时间】:2020-05-20 19:02:48
【问题描述】:

我是递归查询的新手,如果这是一个简单的解决方案,我深表歉意,但我认为这会有点困难。

我得到了一个层次结构表,其中定义了多个级别的父子关系,我需要一种方法来显示一个项目可能具有的所有可能关系。还有一些我无法摆脱的循环关系 - 我不确定这是否会导致问题。

例如,原始数据如下所示:

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),但我希望有一个使用递归查询的更好方法。

希望这是有道理的,并在此先感谢!

【问题讨论】:

  • 层次结构 - 不是“层次结构” ....
  • 您的示例数据中有些地方没有意义。最后两行形成一个循环。层次结构没有循环。这是一个错字,还是你的数据中真的有循环?你的人际关系在现实生活中的意义是什么?无论如何,这肯定会导致一些问题。
  • 不幸的是,数据中有循环。现实生活中的关系概述了要安装的部件的可互换性。这概述了一种方式的互换性,因此例如 ABC2 可以安装在 ABC1 的位置,但不能反过来安装。在循环的情况下,它们在技术上是双向可互换的,但前提是满足某些其他条件,因此必须将它们作为单向可互换循环进行管理。不是我的设计,但这就是我必须使用的。希望这是有道理的。

标签: sql oracle recursive-query


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2015-11-23
    • 1970-01-01
    • 2020-04-17
    • 2015-10-15
    • 2014-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多