2015-02-05 62 views
3

我使用SQL-server.I有一個表的樣子:儘量避免參加大型表

Name timestamp    var1  
Bill 2015-02-05 10:10:10  x1 
Bill 2015-02-05 10:10:11  x2 
... 
Jim  2015-02-05 10:10:10  y1 
Jim  2015-02-05 10:10:11  y2 
... 
John 2015-02-05 10:10:10  z1 
John 2015-02-05 10:10:11  z2 

表是非常大的發言權一個百萬行和時間戳每秒更新一次。我想選擇在任何一分鐘內var1值變化delta var1(即x61-x1或x62-x2等)在5-7之間的人。這是我加入的代碼。

declare @duration int 
set @duration = 60 

    SELECT a.name, 
      a.var1-b.var1 AS change 
From Table1 a 
inner join Table1 b 
    on a.name = b.name 
    and a.timestamp = b.timestamp + @duration 
Where change between 5 and 7 

但是,我知道有兩個主要問題。

  1. 時間戳不能像這樣比較。有什麼方法可以解決它嗎?
  2. 我的表太大。如果每次加入,運行時間都會很長。任何想法,以避免這一點?
+1

你有沒有索引名稱和時間戳在你的表上?如果不是,請添加一個。 – 2015-02-05 16:21:49

+3

1百萬行不是「非常大」;) – Jamiec 2015-02-05 16:21:57

+0

我不太明白你想要達到什麼。你想選擇所有更新的時間戳相對接近(在一些三角洲內)的人? – ddinchev 2015-02-05 16:23:17

回答

2

假設@duration的分鐘數是加入應該像

.... 
and a.timestamp = DATEADD(mi,@duration,b.timestamp) 
.... 
+0

感謝您的dateadd函數 – user4441082 2015-02-05 16:43:09

1

如果您使用的是SQL Server 2012或更高版本,則可以使用LAG()-window函數解決此問題,因爲可以將該行的值與前一個值進行比較,並且如果您對它們進行了排序正確的,這是你所感興趣的一個。

https://msdn.microsoft.com/en-us/library/hh231256.aspx

這也許應該是可以調整的「差距及離島」問題的解決方案,這一個了。

編輯,發現伊茨克奔甘後我還記得前面閱讀,這屬於「特殊島嶼」類別:

http://sqlmag.com/sql-server-2012/solving-gaps-and-islands-enhanced-window-functions

+0

感謝您的信息 – user4441082 2015-02-05 16:42:41

1

請嘗試以下

declare @duration int 
set @duration = 60 

SELECT 
    a.name, 
    (SELECT TOP (1) a.var1-b.var1 
     FROM Table1 b 
     WHERE a.name = b.name 
      and a.timestamp = DATEADD(second, @duration , b.timestamp) 
      AND (a.var1-b.var1) between 5 and 7) As Change 
FROM 
    Table1 AS a 

我希望這可能會有所幫助。