使用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
我的问题很简单,选择已运行一小时,仍在运行:'( 我确定我的代码中有问题,但是我不知道在哪里。
答案 0 :(得分:3)
您遗漏了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(如果将来有大量示例数据,您可以在将来提供;或者提供更小的示例来显示问题...)