比较连续行中的数据

时间:2014-12-01 20:48:13

标签: sql sql-server

我有一个包含2个字段的表:TimeStamp(日期和时间)和值(数字)。

我需要一个(高效的)查询来查找Value字段比上一行更小的那些行,它们是按TimeStamp排序的。我提供了一小组数据作为例子:

Timestamp                Value
-------------            -----------
2014/12/01 18:30:10      500
2014/12/01 18:30:20      510
2014/12/01 18:30:30      520
2014/12/01 18:30:40      530
2014/12/01 18:30:50      5        <- I want to have this row returned
2014/12/01 18:31:00      25
2014/12/01 18:31:10      40
2014/12/01 18:31:20      13       <- And this one as well.
2014/12/01 18:31:30      18
2014/12/01 18:31:40      23

每10秒钟会插入一行,数据会持续数年,所以我希望行数增长很快。

如果无法生成有效的查询,我想在行插入上创建一个触发器来检索前一行,检查Value字段,如果插入的行的值较小,则插入一条记录进入另一张桌子。你怎么看待这件事?

谢谢!

3 个答案:

答案 0 :(得分:2)

在SQL Server 2012+中,您将使用lag()

insert into othertable(col1 . . . )
    select t.*
    from (select t.*, lag(value) over (order by timestamp) as prev_value
          from table t
         ) t
    where value < prev_value;

为了提高性能,您需要table(timestamp, value)上的索引。

在早期版本的SQL Server中,您可以使用相关子查询或cross apply

如果您定期这样做,例如每晚,那么您将需要where条款。小心边界条件(如果值在午夜时间下降,你仍然想要抓住它)。

答案 1 :(得分:1)

我从没想过相关的子查询。我认为这对我有用:

SELECT 
    t.TimeStamp, 
    t.Valor
FROM 
    Tabla1 AS t
WHERE 
    t.Valor <
    (
        SELECT TOP 1
            t2.Valor
        FROM
            Tabla1 AS t2
        WHERE
            t2.TimeStamp < t.TimeStamp
        ORDER BY
            t2.TimeStamp ASC
    )

答案 2 :(得分:0)

另一种解决方案是这样的:

select *
from
    (select dt, value, ROW_NUMBER() OVER(ORDER BY dt asc) as RowNo
    from test) t1
where t1.value < 
    (select value 
    from
        (select dt, value, ROW_NUMBER() OVER(ORDER BY dt asc) as RowNo
        from test) t2
    where t2.RowNo = t1.RowNo - 1
)

在这里测试:http://sqlfiddle.com/#!3/336bc/11