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

SQL Server递归计算列需求:基于种子行递推BOP与EOP列

用递归CTE实现依赖前一行的BOP/EOP计算

没问题,递归CTE(通用表表达式)刚好能解决这种需要基于前一行结果计算当前行的场景!我给你一步一步拆解实现方法,结合你的需求写具体的SQL代码。

核心思路

你的需求里,每一行的BOP等于前一行的EOP,EOP等于前一行EOP加上当前行的IN减去OUT,这完全符合递归查询的逻辑:

  • 先定义锚点成员:也就是你的种子行(第一行),计算它的初始BOP和EOP
  • 再定义递归成员:通过关联前一行的结果,计算当前行的两个字段

具体SQL示例

假设你的表名为stock_movement,包含排序用的sequence_id(用来保证行的顺序,也可以用日期、时间戳这类字段)、IN、OUT列。下面是适配的代码:

WITH recursive stock_calculation AS (
    -- 锚点成员:处理种子行(第一行)
    SELECT
        sequence_id,
        IN,
        OUT,
        -- 这里替换成你的种子行初始BOP值,比如如果初始库存是100就写100
        0 AS BOP,
        0 + IN - OUT AS EOP
    FROM stock_movement
    WHERE sequence_id = 1 -- 定位到种子行,也可以用ORDER BY sequence_id LIMIT 1
    UNION ALL
    -- 递归成员:基于前一行计算当前行
    SELECT
        sm.sequence_id,
        sm.IN,
        sm.OUT,
        sc.EOP AS BOP,
        sc.EOP + sm.IN - sm.OUT AS EOP
    FROM stock_movement sm
    JOIN stock_calculation sc ON sm.sequence_id = sc.sequence_id + 1
)
-- 输出最终计算结果
SELECT sequence_id, IN, OUT, BOP, EOP FROM stock_calculation ORDER BY sequence_id;

关键注意事项

  • 排序字段必须明确:不管用sequence_id还是日期,一定要保证每行能准确关联到它的前一行,否则计算结果会乱掉。如果是按日期排序,把关联条件改成sm.transaction_date = sc.transaction_date + INTERVAL '1 day'(根据数据库语法调整)即可。
  • 种子行的初始值:如果你的种子行已经有预设的BOP值,直接把锚点成员里的0换成表中的BOP字段就行,比如SELECT ... BOP, BOP + IN - OUT AS EOP ...。
  • 数据库语法适配:不同数据库对递归CTE的语法略有差异,比如MySQL 8.0+需要加RECURSIVE关键字,SQL Server可以直接用WITH,PostgreSQL支持WITH RECURSIVE,根据你的数据库调整即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:13:17