CONNECT BY永无止境

CONNECT BY never ending

我在使用 Oracle START WITH / CONNECT BY 进行递归时遇到了一些麻烦。

给定 table id_stringidordreprec,其中 id_stringid_ordre 的串联. prec 具有相同 id 的两个元素之间的 link(1_1,1,1,2 被 link 编辑为 1_1,1,2,null)。 table 包含 500 行,其中 196 行是唯一的 id_string

我想从此 table 中检索所有 linked 行,给定以 id_string 等于 id|| '_' || ordre 和 linked 到 ordreprec,我使用以下请求

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

我的问题很简单,select已经运行一个小时了,还是运行:'( 我确定我的代码有问题,但我不知道在哪里。

数据文件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(如果有那么多样本数据,您可以在将来提供样本数据;或者提供一个更小的样本来显示问题...)