非连续行中的值之间的差异

时间:2017-06-02 16:57:44

标签: sql-server tsql sql-server-2012

我有以下数据集。每天都有一个值,它总是超过前一天的值。

TimeStamps以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天的差异。在上面的示例中,01/06/2017行的新1DayDifference将是Value减去02/06/2017行的Value ..

第二,7天的差异。 02/06/2017行的新7DayDifference将是Value减去26/05/2017行的Value

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中从哪里开始。

3 个答案:

答案 0 :(得分:1)

使用LAG获取以前的值,信息look here

尝试这样的事情:

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

答案 1 :(得分:0)

您可以使用以下链接

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

答案 2 :(得分:0)

正如我所评论的那样,您可以尝试使用row_number创建一个列来标识每一行并在自连接中使用结果。

如果你不喜欢使用#temp表,你可以使用具有相同效果的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