Sql server 非连续行中的值之间的差异
我有下面的数据集。每天都有一个值,该值始终大于前一天的值 时间戳以Sql server 非连续行中的值之间的差异,sql-server,tsql,sql-server-2012,Sql Server,Tsql,Sql Server 2012,我有下面的数据集。每天都有一个值,该值始终大于前一天的值 时间戳以dd/mm/yyyy格式给出 TimeStamp Device Value ------------------- ------ --------- 25/05/2017 00:00:00 A_Mill 150292432 26/05/2017 00:00:00 A_Mill 150507748 27/05/2017 00:00:00 A_Mill 150745778 28/05/2017
dd/mm/yyyy
格式给出
TimeStamp Device Value
------------------- ------ ---------
25/05/2017 00:00:00 A_Mill 150292432
26/05/2017 00:00:00 A_Mill 150507748
27/05/2017 00:00:00 A_Mill 150745778
28/05/2017 00:00:00 A_Mill 150918209
29/05/2017 00:00:00 A_Mill 151201139
30/05/2017 00:00:00 A_Mill 151413118
31/05/2017 00:00:00 A_Mill 151617243
01/06/2017 00:00:00 A_Mill 151798964
02/06/2017 00:00:00 A_Mill 151985446
我需要添加两列:
首先,1天的差异。在上述示例中,2017年6月1日
行的新1日差
将是值
减去2017年6月2日
行的值
第二,7天的差异。2017年6月2日
行新的7天差异
将是值
减去2017年5月26日
行的值
TimeStamp Device Value 1DayDifference 7DayDifference
------------------- ------ --------- -------------- --------------
25/05/2017 00:00:00 A_Mill 150292432 215316
26/05/2017 00:00:00 A_Mill 150507748 238030
27/05/2017 00:00:00 A_Mill 150745778 172431
28/05/2017 00:00:00 A_Mill 150918209 282930
29/05/2017 00:00:00 A_Mill 151201139 211979
30/05/2017 00:00:00 A_Mill 151413118 204125
31/05/2017 00:00:00 A_Mill 151617243 181721 1506532
01/06/2017 00:00:00 A_Mill 151798964 186482 1477698
02/06/2017 00:00:00 A_Mill 151985446
这在Excel中很容易实现,但我不知道从哪里开始在t-SQL中使用它。您可以使用lead,如下所示
select *, [1DayDifference]= lead([value]) over(partition by Device order by [Timestamp]) - [Value] ,
[7dayDifference] = lead([value]) over(partition by Device order by [Timestamp]) -
lag([value], 6, null) over(partition by Device order by [Timestamp])
from Yourdevice
为7DayDifference更新了正确的逻辑
输出如下:
+-------------------------+--------+-----------+----------------+----------------+
| Timestamp | Device | value | 1DayDifference | 7dayDifference |
+-------------------------+--------+-----------+----------------+----------------+
| 2017-05-25 00:00:00.000 | A_Mill | 150292432 | 215316 | NULL |
| 2017-05-26 00:00:00.000 | A_Mill | 150507748 | 238030 | NULL |
| 2017-05-27 00:00:00.000 | A_Mill | 150745778 | 172431 | NULL |
| 2017-05-28 00:00:00.000 | A_Mill | 150918209 | 282930 | NULL |
| 2017-05-29 00:00:00.000 | A_Mill | 151201139 | 211979 | NULL |
| 2017-05-30 00:00:00.000 | A_Mill | 151413118 | 204125 | NULL |
| 2017-05-31 00:00:00.000 | A_Mill | 151617243 | 181721 | 1506532 |
| 2017-06-01 00:00:00.000 | A_Mill | 151798964 | 186482 | 1477698 |
| 2017-06-02 00:00:00.000 | A_Mill | 151985446 | NULL | NULL |
+-------------------------+--------+-----------+----------------+----------------+
正如我所评论的,您可以尝试使用row_number创建一个列来标识每一行,并在自联接中使用结果 如果你不喜欢使用临时表格,你可以使用同样效果的CTE
create table MyTable
(
[TimeStamp] datetime not null
,[Device] varchar(100) not null
,[Value] int not null
)
GO
set dateformat dmy
insert into MyTable
values
('25/05/2017 00:00:00','A_Mill',150292432)
,('26/05/2017 00:00:00','A_Mill',150507748)
,('27/05/2017 00:00:00','A_Mill',150745778)
,('28/05/2017 00:00:00','A_Mill',150918209)
,('29/05/2017 00:00:00','A_Mill',151201139)
,('30/05/2017 00:00:00','A_Mill',151413118)
,('31/05/2017 00:00:00','A_Mill',151617243)
,('01/06/2017 00:00:00','A_Mill',151798964)
,('02/06/2017 00:00:00','A_Mill',151985446)
GO
select *
,ROW_NUMBER() OVER(ORDER BY [TimeStamp] ASC) AS Row#
into #temp
from MyTable
select t0.*
, t1.Value - t0.Value as [1 day Difference]
, t2.Value - t0.Value as [7 day Difference]
from #temp t0
left join #temp t1 on t1.Row# = t0.Row# +1
left join #temp t2 on t2.Row# = t0.Row# +7
结果
2017-05-25 00:00:00.000 A_Mill 150292432 1 215316 1506532
2017-05-26 00:00:00.000 A_Mill 150507748 2 238030 1477698
2017-05-27 00:00:00.000 A_Mill 150745778 3 172431 NULL
2017-05-28 00:00:00.000 A_Mill 150918209 4 282930 NULL
2017-05-29 00:00:00.000 A_Mill 151201139 5 211979 NULL
2017-05-30 00:00:00.000 A_Mill 151413118 6 204125 NULL
2017-05-31 00:00:00.000 A_Mill 151617243 7 181721 NULL
2017-06-01 00:00:00.000 A_Mill 151798964 8 186482 NULL
2017-06-02 00:00:00.000 A_Mill 151985446 9 NULL NULL
使用LAG获取以前的值,以获取信息 试着这样做:
select [TimeStamp], [Device], [Value],
lag(value) over(order by [TimeStamp]) - [Value] as [1DayDifferance],
lag(value, 6) over(order by [TimeStamp]) - [Value] as [7DayDifferance]
from yourtable
使用row_编号,并从中自动加入每一行,下一行是我的同一个解决方案:)哇,这是一个多么好的回答,我有它的工作不,谢谢大家的回复,它帮了我很多:)你提供了msdn的法语版本链接=)这是一个很好的解决方案,顺便说一句,它只能从sql 2012+lol开始工作是的,这是真的,我改变我的链接,谢谢。至于SQL Server的版本,这正是请求中指定的版本。:)Jean,如果您使用的是2012年以下的版本,那么您就有其他问题了。@Josh Nah,我使用的是2016,但这里有很多人使用的策略是“如果它正常工作,就不要碰它”,所以我不怀疑偶尔会发现SQL Server 2008--