You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL CTE自递归无限循环问题及递推计算逻辑修正求助

问题与修正

问题背景

需要实现递归计算逻辑:

  • 当rn=1时,i = x / y
  • 当rn>1时,i = 上一条记录的i值 / 当前y值

原代码运行时陷入无限循环,且计算结果不符合预期,期望输出如下:

rnxyi
120210.00
23033.33
34040.83

原代码:

drop table if exists #tmp

create table #tmp
(
    rn int,
    x int,
    y int
)

insert into #tmp
values (1, 20, 2),
       (2, 30, 3),
       (3, 40, 4);

with cte as
(
    select 
        *, x / y as i
    from 
        #tmp curr
    where 
        rn = 1
    union all
    select 
        curr.rn, curr.x, curr.y, prev.x / prev.y / curr.y as i  
    from 
        cte curr
    join 
        #tmp prev on prev.rn = curr.rn + 1
)
select *
from cte
option (maxrecursion 0)

问题排查

  1. 无限循环原因:递归CTE的关联条件逻辑错误。原代码中用递归CTE的当前记录关联#tmp中rn = curr.rn + 1的记录,且设置了maxrecursion 0(无递归次数限制),导致每次递归都会生成新的记录,没有终止条件,最终无限循环。
  2. 计算逻辑错误:递归部分的i计算错误,应该使用上一次递归得到的i值除以当前y,而非重新计算上一条的x/y再除以当前y;同时原代码用整数除法,会丢失精度。

修正后的代码

drop table if exists #tmp

create table #tmp
(
    rn int,
    x int,
    y int
)

insert into #tmp
values (1, 20, 2),
       (2, 30, 3),
       (3, 40, 4);

with cte as
(
    -- 锚点成员:初始化rn=1的记录,转换为浮点除法保留精度
    select 
        rn,
        x,
        y,
        cast(x * 1.0 / y as decimal(10,2)) as i
    from 
        #tmp
    where 
        rn = 1
    union all
    -- 递归成员:关联下一条rn的记录,用上一次的i除以当前y
    select 
        t.rn,
        t.x,
        t.y,
        cast(c.i / t.y as decimal(10,2)) as i
    from 
        cte c
    join 
        #tmp t on t.rn = c.rn + 1
)
select *
from cte

运行结果

执行后得到符合预期的输出:

rnxyi
120210.00
23033.33
34040.83

内容的提问来源于stack exchange,提问作者sickless

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 20:14:53