我想计算一个列的移动平均值,这需要使用前一个记录中的参数进行算术计算。
我有抄表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
我想将此选择到表格中进行报告。
- 编辑 -
我得到了Divide 0错误并决定计算阅读X - 单独阅读Y作为ReadingDiff。
LEAD(MeterReading, 1, 0) OVER (PARTITION BY MeterID ORDER BY MeterReading) - MeterReading AS MeterDiff
因为选择列表中有超过1个MeterID,我如何阻止它计算MeterID 1的最后一个记录和MeterID 2的第一个记录之间的MeterDiff?我不能将每个MeterID的第一条记录设置为0吗?
答案 0 :(得分:4)
这将是这样的:
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
。