SQL如何使用递归或While循环实现基于前置行的AR(1)模型
实现方案
完全可以通过SQL的递归CTE(公共表表达式)实现该需求,以下是适配SQL Server语法的可运行代码:
递归CTE实现(推荐)
WITH OrderedData AS ( -- 给原始数据按周期排序生成连续行号,避免周期编号不连续导致关联错误 SELECT Period, [Values], -- Values为SQL保留字,用方括号包裹避免语法报错 ROW_NUMBER() OVER (ORDER BY Period) AS rn FROM 你的实际表名 -- 替换为你自己的表名 ), RecursiveAR AS ( -- 锚点成员:取首行数据,AR等于当前行Values SELECT Period, [Values], CAST([Values] AS FLOAT) AS AR, -- 统一转为浮点型避免整数除法丢失精度 rn FROM OrderedData WHERE rn = 1 UNION ALL -- 递归成员:依次取后续行,用上一行AR和当前行Values计算平均值 SELECT o.Period, o.[Values], (r.AR + o.[Values]) / 2.0 AS AR, o.rn FROM RecursiveAR r INNER JOIN OrderedData o ON r.rn + 1 = o.rn ) -- 输出最终结果 SELECT Period, [Values], AR FROM RecursiveAR ORDER BY Period -- 数据量超过100行时打开下方注释取消递归深度限制 -- OPTION (MAXRECURSION 0) ;
While循环实现
如果你的场景数据量极大,也可以用While循环实现:
-- 创建带行号的临时表存储原始数据和计算结果 SELECT Period, [Values], ROW_NUMBER() OVER (ORDER BY Period) AS rn, CAST(NULL AS FLOAT) AS AR INTO #TempAR FROM 你的实际表名; -- 初始化首行AR值 UPDATE #TempAR SET AR = [Values] WHERE rn = 1; -- 循环计算后续行AR DECLARE @currentRow INT = 2, @totalRow INT = (SELECT MAX(rn) FROM #TempAR); WHILE @currentRow <= @totalRow BEGIN UPDATE t SET AR = (prev.AR + t.[Values]) / 2.0 FROM #TempAR t INNER JOIN #TempAR prev ON t.rn -1 = prev.rn WHERE t.rn = @currentRow; SET @currentRow = @currentRow + 1; END -- 输出结果 SELECT Period, [Values], AR FROM #TempAR ORDER BY Period; -- 清理临时表 DROP TABLE #TempAR;
注意事项
- 两种实现都默认按Period字段升序排序计算,如果你有特殊的排序规则可以调整
ORDER BY Period的逻辑 - 如果你的Values字段本身就是浮点/小数类型,可以去掉
CAST([Values] AS FLOAT)的转换逻辑
内容的提问来源于stack exchange,提问作者Apeyko
相关产品推荐
相关产品推荐

