基于SQL Server实现Excel中Total Avg累计平均的计算逻辑
在SQL Server中实现累计递推平均计算
你的需求本质是实现递推式累计平均,每一行的Total Avg依赖上一行的计算结果,结合当前行的C(%)和Day字段得出。下面提供两种可行的实现方案:
方法一:递归CTE(适配明确行顺序的场景)
假设你的数据表结构如下(替换为实际表名和字段名即可):
CREATE TABLE YourTable ( RowNum INT, -- 对应Excel行号,用于确定计算顺序 TotalAvg_Init DECIMAL(5,2), -- 初始行(第3行)的Total Avg值 C_Percent DECIMAL(5,2), -- 对应C(%)字段 Day INT -- 对应Field Day/Day字段 );
插入示例测试数据(对应你给出的第3-5行内容):
INSERT INTO YourTable (RowNum, TotalAvg_Init, C_Percent, Day) VALUES (3, 0, NULL, NULL), -- 初始行,无C(%)和Day值 (4, NULL, 50, 4), (5, NULL, 0, 5);
使用递归CTE完成递推计算:
WITH RecursiveCTE AS ( -- 锚点成员:取初始行的基础值 SELECT RowNum, TotalAvg_Init AS CurrentTotalAvg, C_Percent, Day FROM YourTable WHERE RowNum = 3 UNION ALL -- 递归成员:逐行计算递推结果 SELECT t.RowNum, ROUND((r.CurrentTotalAvg + t.C_Percent) / t.Day, 2) AS CurrentTotalAvg, t.C_Percent, t.Day FROM YourTable t JOIN RecursiveCTE r ON t.RowNum = r.RowNum + 1 ) SELECT RowNum, CurrentTotalAvg AS [Total Avg (%)], C_Percent AS [C(%)], Day FROM RecursiveCTE ORDER BY RowNum;
执行后会得到和Excel一致的结果:
| RowNum | Total Avg (%) | C(%) | Day |
|---|---|---|---|
| 3 | 0 | NULL | NULL |
| 4 | 13 | 50 | 4 |
| 5 | 3 | 0 | 5 |
方法二:窗口函数累加(适配可转换为累计和的场景)
如果你的递推逻辑可以转化为累计和形式(本质是加权平均的变形),也可以用窗口函数实现。这里你的公式可转换为:TotalAvg(n) = (初始TotalAvg值 + SUM(C(%)从第4行到当前行)) / 当前行Day值
对应的SQL语句:
SELECT RowNum, ROUND((0 + SUM(C_Percent) OVER (ORDER BY RowNum ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) / Day, 2) AS [Total Avg (%)], C_Percent AS [C(%)], Day FROM YourTable WHERE RowNum >=4 UNION ALL SELECT RowNum, TotalAvg_Init, C_Percent, Day FROM YourTable WHERE RowNum=3 ORDER BY RowNum;
关键注意事项
- 必须保证表中有明确的排序字段(比如示例中的
RowNum),否则无法保证计算顺序和Excel一致。 - 根据实际数据精度调整
DECIMAL的参数,避免精度丢失。 - 若表中有更多行,递归CTE会自动按顺序递推计算,无需修改核心逻辑。
内容的提问来源于stack exchange,提问作者nazrin ahmad
相关产品推荐
相关产品推荐

