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

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

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

  1. PN INT
  2. ===== =====
  3. ABC1 ABC2
  4. ABC1 ABC9
  5. ABC2 ABC3
  6. ABC3 ABC4
  7. DEF1 DEF2
  8. GHI1 GHI2
  9. GHI2 GHI1

我需要查询结果如下所示:

  1. PN INT
  2. ===== =====
  3. ABC1 ABC2
  4. ABC1 ABC9
  5. ABC1 ABC3
  6. ABC1 ABC4
  7. ABC2 ABC3
  8. ABC2 ABC4
  9. ABC3 ABC4
  10. DEF1 DEF2
  11. GHI1 GHI2
  12. GHI2 GHI1

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

dojqjjoe

dojqjjoe1#

为每一行构建层次结构,返回 pn 对于根行。
你可以这样做 connect by 使用 connect_by_root :

  1. create table t (
  2. c1 varchar2(4), c2 varchar2(4)
  3. );
  4. insert into t values ( 'ABC1', 'ABC2' );
  5. insert into t values ( 'ABC1', 'ABC9' );
  6. insert into t values ( 'ABC2', 'ABC3' );
  7. insert into t values ( 'ABC3', 'ABC4' );
  8. insert into t values ( 'DEF1', 'DEF2' );
  9. insert into t values ( 'GHI1', 'GHI2' );
  10. insert into t values ( 'GHI2', 'GHI1' );
  11. commit;
  12. select * from (
  13. select distinct connect_by_root c1 rt, c2
  14. from t
  15. connect by nocycle c1 = prior c2
  16. )
  17. where rt <> c2
  18. order by rt, c2;
  19. RT C2
  20. ABC1 ABC2
  21. ABC1 ABC3
  22. ABC1 ABC4
  23. ABC1 ABC9
  24. ABC2 ABC3
  25. ABC2 ABC4
  26. ABC3 ABC4
  27. DEF1 DEF2
  28. GHI1 GHI2
  29. GHI2 GHI1

这个 nocycle 子句检测循环并停止处理。
或递归 with 通过在每次迭代中选择根的值:

  1. with tree ( c1, c2, rt ) as (
  2. select c1, c2, c1 from t
  3. union all
  4. select t.c1, t.c2, tree.rt
  5. from tree
  6. join t
  7. on t.c1 = tree.c2
  8. ) cycle c1 set is_cycle to 'Y' default 'N'
  9. select rt, c2
  10. from tree
  11. where is_cycle = 'N'
  12. and rt <> c2
  13. order by rt, c2;
  14. RT C2
  15. ABC1 ABC2
  16. ABC1 ABC3
  17. ABC1 ABC4
  18. ABC1 ABC9
  19. ABC2 ABC3
  20. ABC2 ABC4
  21. ABC3 ABC4
  22. DEF1 DEF2
  23. GHI1 GHI2
  24. GHI2 GHI1

这个 cycle 子句检测循环。

展开查看全部

相关问题