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--