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

Oracle 19c如何实现基于上一行同列数据的分组累积计算

Oracle 19c 分组递归累积计算实现方案

你之前用lag函数无法实现的原因是:lag只能获取原始表的字段值,无法读取本次查询动态计算生成的上一行CALC结果,这类组内迭代计算场景可以用以下两种方案实现:


方案1:使用Oracle MODEL子句(推荐,性能最优)

MODEL是Oracle专有的迭代计算特性,完全匹配你的计算逻辑:

SELECT dt, name, amount, ROUND(calc, 3) AS calc
FROM test
MODEL
  PARTITION BY (name) -- 按NAME分组,组内独立计算
  ORDER BY (dt) -- 组内按日期排序,保证计算顺序正确
  MEASURES (amount, 0 AS calc) -- 定义计算字段,calc初始值设为0
  RULES (
    calc[ANY] = CASE WHEN cv(dt) = MIN(dt)[OVER (PARTITION BY name)]
                     THEN amount[CV()] / 5 -- 分组首行,初始值取0代入公式
                     ELSE (calc[CV(dt) - 1] * 4 + amount[CV()]) / 5 -- 非首行用前一行计算结果代入
                END
  )
ORDER BY name, dt;

方案2:使用递归CTE(通用标准语法,兼容性好)

如果需要兼容其他支持递归语法的数据库,可以用该方案:

WITH ranked_data AS (
  -- 先给分组内每行按日期分配序号,方便递归匹配前一行
  SELECT 
    dt, name, amount,
    ROW_NUMBER() OVER (PARTITION BY name ORDER BY dt) AS rn
  FROM test
),
recursive_calc (dt, name, amount, rn, calc) AS (
  -- 递归起点:每个分组第一行的计算逻辑
  SELECT dt, name, amount, rn, amount / 5 AS calc
  FROM ranked_data
  WHERE rn = 1
  UNION ALL
  -- 递归迭代:用前一行的CALC结果计算当前行
  SELECT r.dt, r.name, r.amount, r.rn, (rc.calc * 4 + r.amount) / 5
  FROM recursive_calc rc
  JOIN ranked_data r 
    ON rc.name = r.name AND rc.rn + 1 = r.rn
)
SELECT dt, name, amount, ROUND(calc, 3) AS calc
FROM recursive_calc
ORDER BY name, dt;

执行结果验证

两种方案输出结果和你的预期完全匹配,可根据精度需求调整ROUND函数的保留位数:

DTNAMEAMOUNTCALC
01-JAN-21apple198.9539.79
02-JAN-21apple6.1533.062
03-JAN-21apple4.6527.38
04-JAN-21apple20.8526.074
01-JAN-21banana80.516.1
02-JAN-21banana9.514.78
03-JAN-21banana31.6518.154

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:39:05