2014-12-01 53 views
0

我有一个包含2个字段的表格: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字段,并且如果插入的行具有较小的值,则将记录插入另一张桌子。你怎么看待这件事?

谢谢!

+2

您正在使用什么版本的SQL Server? – Taryn 2014-12-01 20:51:30

回答

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条款。注意边界条件(如果价值在午夜之后下降,你仍然想要知道)。

+0

这样的事情会好吗? – Jordi 2014-12-01 21:15:27

+1

@Jordi。 。 。您的解决方案也将工作。你仍然需要性能指数。 – 2014-12-01 21:36:42

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