我在使用 Oracle START WITH/CONNECT BY 进行递归时遇到了一点麻烦。
给定一个表id_string
、id
、ordre
、prec
id_string
是id_ordre
的串联,并prec
具有相同id
的两个元素之间的链接(1_1,1,1,2
链接到1_1,1,2,null
)。该表包含 500 行和 196 个唯一id_string
。
我想从这个表中检索所有链接的行,以id_string
等于 id|| '_' || ordre
开头并通过 ordre
和 prec
链接,我使用以下请求
SELECT tda.*
FROM T_DRU_ALL tda
START WITH tda.ID|| '_' || tda.ORDRE = tda.id_string
CONNECT BY NOCYCLE PRIOR tda.ORDRE = tda.PREC and tda.id_string = tda.id_string
order by 1,2,3
我的问题很简单,选择已经运行了一个小时并且仍在运行:'(我确定我的代码有问题,但我不知道在哪里。
数据文件 https://pastebin.com/R66T3hAu
你缺少一个PRIOR
,这可能是你的周期来自哪里,也是你添加NOCYCLE
的原因;没有它,tda.id_string = tda.id_string
总是正确的。
所以乍一看你可以改变:
CONNECT BY NOCYCLE PRIOR tda.ORDRE = tda.PREC and PRIOR tda.id_string = tda.id_string
或删除NOCYCLE
:
CONNECT BY PRIOR tda.ORDRE = tda.PREC and PRIOR tda.id_string = tda.id_string
但是,这仍然永远不会结束;奇怪的是,只是将术语重新排列为看似相同的逻辑结果(但对我来说无论如何扫描得更好):
或重新排列术语(这对我来说扫描得更好,但应该没有任何实际效果 - 不知道为什么我认为我早先看到了一个!
CONNECT BY tda.id_string = PRIOR tda.id_string AND tda.PREC = PRIOR tda.ORDRE
现在可以正常工作:
ID_STRING ID ORDRE PREC
--------- ---------- ---------- ----------
7682_2 7682 2
7682_2 7682 13 2
7682_2 7682 14 13
7690_6 7690 6
7690_7 7690 7
7693_2 7693 2
7693_2 7693 9 2
7693_2 7693 10 9
...
371 rows selected.
就个人而言,我可能会提出起始条件
START WITH tda.PREC IS NULL
而不是连接值 - 无论如何,它与您拥有的数据的结果相同。
db<>fiddle(如果数据太多,您可以在将来提供样本数据;或者提供一个更小的样本来显示问题......