2014-12-01 31 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