连接永无止境

时间:2019-01-31 15:40:42

标签: sql oracle connect-by

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

给出一个表id_stringidordreprec,其中id_stringid_ordre的串联。 prec和具有相同id的两个元素之间的链接(1_1,1,1,2链接到1_1,1,2,null)。 该表包含500行,其中包含196个唯一的id_string

我想从给定的id_string等于id|| '_' || ordre并通过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

我的问题很简单,选择已运行一小时,仍在运行:'( 我确定我的代码中有问题,但是我不知道在哪里。

数据文件https://pastebin.com/R66T3hAu

1 个答案:

答案 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(如果将来有大量示例数据,您可以在将来提供;或者提供更小的示例来显示问题...)