sql server选择第一次出现的数据更改

时间:2017-10-05 08:45:44

标签: sql-server sql-server-2008-r2 gaps-and-islands

我有一个 sql server 2008 r2 数据库。

我有一个名为hystrealdata的表,其中每隔 n秒存储一台automotiv机器的生产数据。因此,它的结构如下:

dataregvalue                                        timestamp             
--------------------------------------------------------------------------
0                                                   1507190476            
0                                                   1507190577            
0                                                   1507190598            
0                                                   1507190628            
1                                                   1507190719            
1                                                   1507190750            
1                                                   1507190780            
1                                                   1507190811            
1                                                   1507190841            
2                                                   1507190861            
2                                                   1507190892            
2                                                   1507190922            
2                                                   1507190953            
2                                                   1507190983      
5                                                   1507190477      

我需要在第一行中选择第一次出现dataregvalue,然后选择下一个dataregvalue与前一行之间的差异。在这个数据旁边,我希望得到dataregvalue可以使用的第一个时间戳。选择的一个例子是:

data_change     timestamp             
---------------------------
0                1507190476    <- first time in which the dataregvalue is 0    
1                1507190719    <- first time in which the dataregvalue changes        
1                1507190861    <- first time in which the dataregvalue changes        
3                1507190477    <- first time in which the dataregvalue changes 

如果这太困难了,可以在新列中获取有关dataregvalues之间差异的信息,如下所示:

dataregvalue      data_change      timestamp             
---------------------------------------------
    0             0                1507190476
    1             1                1507190719
    2             1                1507190861
    5             3                1507190477

如何做到这一点? 提前谢谢!

1 个答案:

答案 0 :(得分:3)

您可以使用LAG分析函数来读取分区中的先前值,例如:

Select 
    dataregvalue,
    dataregvalue - LAG(dataregvalue,1) OVER (ORDER BY timestamp) as data_change,
    timestamp
from MyTable

这将返回所有行的更改。存在更改的行将具有data_change值> 0。第一行将具有NULL值,因为没有前一行。

不幸的是,您无法在WHERE子句中引用data_change。您必须使用CTE:

WITH changes as (
    Select 
        dataregvalue,
        dataregvalue - LAG(dataregvalue,1) OVER (ORDER BY timestamp) as data_change,
        timestamp
    from MyTable
)
select * 
from changes
where 
    data_change >0 or 
    data_change is null

LAG和相应的LEAD函数也可用于检测序列中的间隙和孤岛。每行的ID都比前一行大一个。在间隙中,差异将> 1。