之前已经问过这个问题并且特别为MySQL做了很好的回答,但是我非常感谢你们帮助我们为SQL Server翻译这个问题。之前的帖子已关闭,我不想重新打开它们,因为它们已经很老了。
以下是要查询的数据集,以及查询解决方案的必需输出。下面是这里发布的优秀MySql解决方案(SQL best way to subtract a value of the previous row in the query?)。我的问题是如何使用SQL Server中的变量完成相同的结果。如果这是一个新手问题我很抱歉,但我是SQL Server中的变量新手,并且在尝试根据SQL Server中的变量的MSDN文档转换为SQL Server时失败了。
感谢您的帮助!
select
EL.SN,
EL.Date,
EL.EL.Value,
if( @lastSN = EL.SN, EL.Value - @lastValue, 0000.00 ) as Consumption,
@lastSN := EL.SN,
@lastValue := EL.Value
from
EnergyLog EL,
( select @lastSN := 0,
@lastValue := 0 ) SQLVars
order by
EL.SN,
EL.Date
我需要通过SN号将消耗值基于前一个消耗值。 这是我的数据:
TABLE EnergyLog
SN Date Value
2380 2012-10-30 00:15:51 21.01
2380 2012-10-31 00:31:03 22.04
2380 2012-11-01 00:16:02 22.65
2380 2012-11-02 00:15:32 23.11
20100 2012-10-30 00:15:38 35.21
20100 2012-10-31 00:15:48 37.07
20100 2012-11-01 00:15:49 38.17
20100 2012-11-02 00:15:19 38.97
20103 2012-10-30 10:27:34 57.98
20103 2012-10-31 12:24:42 60.83
这是我需要的结果:
SN Date Value consumption
2380 2012-10-30 00:15:51 21.01 0
2380 2012-10-31 00:31:03 22.04 1.03
2380 2012-11-01 00:16:02 22.65 0.61
2380 2012-11-02 00:15:32 23.11 0.46
20100 2012-10-30 00:15:38 35.21 0
20100 2012-10-31 00:15:48 37.07 1.86
20100 2012-11-01 00:15:49 38.17 1.1
20100 2012-11-02 00:15:19 38.97 0.8
20103 2012-10-30 10:27:34 57.98 0
20103 2012-10-31 12:24:42 60.83 2.85
答案 0 :(得分:2)
通过使用CTE,您可以获得订购的数据,然后选择上一条记录。
WITH PREVCTE AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY SN ORDER BY MyDate) [RowNum]
FROM @myTable
)
SELECT A.SN,
A.MyDate,
A.[Value],
A.[Value] - COALESCE(B.[Value], A.[Value]) [Consumption]
FROM PREVCTE A LEFT OUTER JOIN PREVCTE B
ON A.RowNum - 1 = B.RowNum AND
A.SN = B.SN
<强> SQL Fiddle Demo 强>
答案 1 :(得分:0)
我之前的解决方案计算了运行总计。在shawnt00发表评论并回顾你提供的例子后,我发现事实并非如此。这应该使解决方案更容易。我相信以下内容适用于SQL 2008,虽然我目前还没有方便的2008盒子来测试它。
;WITH CTE_Ordered AS
(
SELECT
sn,
[date],
value,
ROW_NUMBER() OVER(PARTITION BY sn ORDER BY [date]) AS row_num
FROM
dbo.EnergyLog
)
SELECT
T1.sn,
T1.[date],
T1.value,
T1.value - COALESCE(T2.value, 0) AS consumption
FROM
CTE_Ordered T1
LEFT OUTER JOIN CTE_Ordered T2 ON
T2.sn = T1.sn AND
T2.row_num = T1.row_num - 1
ORDER BY
T1.sn,
T1.row_num
答案 2 :(得分:0)
我相信您正在寻找相邻日期之间的差异。这是一种方式。
select
SN, Date, Value,
Value - (
select coalesce(max(Value), 0) from EnergyLog el2
where el2.SN = el.SN and el2.Date < el.Date
group by el2.SN
) as consumption
from EnergyLog el
如果你总能假设时间间隔是上限的,那么你可以通过缩小回顾窗口的大小来提升性能。这也取决于索引。
select
SN, Date, Value,
Value - (
select coalesce(max(Value), 0) from EnergyLog el2
where el2.SN = el.SN
and el2.Date > dateadd(hour, -48, el.Date) /* max gap 48 hrs? */
and el2.Date < el.Date
group by el2.SN
) as consumption
from EnergyLog el
编辑:根据您在下面关于序列号的评论:
select
SN, Date, Value,
Value - (
select coalesce(max(Value), 0) from EnergyLog el2
where el2.SN = el.SN and el2.SeqNo = el.SeqNo - 1
group by el2.SN
) as consumption
from EnergyLog el
您当然可以使用外连接而不是标量子查询。当然,如果您已经有序列号,那么您不需要row_number()
来生成它们。