CONNECT BY永无止境
CONNECT BY never ending
我在使用 Oracle START WITH / CONNECT BY 进行递归时遇到了一些麻烦。
给定 table id_string
、id
、ordre
、prec
,其中 id_string
是 id_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 到 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
我的问题很简单,select已经运行一个小时了,还是运行:'(
我确定我的代码有问题,但我不知道在哪里。
您缺少一个 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(如果有那么多样本数据,您可以在将来提供样本数据;或者提供一个更小的样本来显示问题...)
我在使用 Oracle START WITH / CONNECT BY 进行递归时遇到了一些麻烦。
给定 table id_string
、id
、ordre
、prec
,其中 id_string
是 id_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 到 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
我的问题很简单,select已经运行一个小时了,还是运行:'( 我确定我的代码有问题,但我不知道在哪里。
您缺少一个 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(如果有那么多样本数据,您可以在将来提供样本数据;或者提供一个更小的样本来显示问题...)