我想计算列的移动平均值,这需要使用先前记录的参数进行算术计算。
我有一个抄表 X 的记录,有日期,我想进行计算 使用公式确定平均速率
(reading x - reading y)/(reading date @ x - reading date @ y)
其中 Y 始终是前一个记录的仪表读数。 DATEDIFF 以天为单位。
Meter | Reading | Date
-------+---------+------------
1 | 39,000 | 1 Jan 2016
1 | 39,200 | 1 Feb 2016
1 | 39,300 | 1 Mar 2016
我想要一个插入计算字段的附加列, 它必须从最新记录中读取,并向后处理 - 因为我有 2 年的阅读经验,而不是第一次。
Meter | Reading | Date | Rate
------+---------+------------+--------------------
1 | 39,000 | 1 Aug 2016 | (200 / 31) = 6.45
1 | 39,200 | 1 Sep 2016 | (100 / 30) = 3.33
1 | 39,300 | 1 Oct 2016 | Z
我想将其选入表格进行报告。
-- 编辑--
我收到除以 0 的错误,因此决定将读数 X - 读数 Y 单独计算为读数差异。
LEAD(MeterReading, 1, 0) OVER (PARTITION BY MeterID ORDER BY MeterReading) - MeterReading AS MeterDiff
因为选择列表中有超过 1 个 MeterID,我如何防止它计算 MeterID 1 的最后一条记录和 MeterID 2 的第一条记录之间的 MeterDiff?我不能将每个 MeterID 的第一条记录设置为 0 吗?
最佳答案
应该是这样的:
select t.*,
( (reading - lag(reading) over (partition by meter order by date)) /
nullif(datediff(day, lag(date) over (partition by meter order by date), date), 0)
)
from t;
如果读取的是一个整数,那么要小心,因为SQL Server做整数除法。所以,您可能想要:
select t.*,
( (1.0*reading - lag(reading) over (partition by meter order by date)) /
nullif(datediff(day, lag(date) over (partition by meter order by date), date), 0)
)
from t;
注意:lag()
是自 2012 版以来在 SQL Server 中实现的 ANSI 标准功能。在此之前,您需要使用计算量更大的方法,例如 outer apply
.
关于sql - 使用先前记录作为变量计算移动平均线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40088272/