2014-10-20 83 views
0

分組行日期之間的平均時間假設我有一個像這樣的表:有效的方式來計算由ID

thedate     ID 
2014-10-20 14:13:42.063 1 
2014-10-20 14:13:43.063 1 
2014-10-20 14:13:47.063 1 
2014-10-20 14:12:50.063 2 
2014-10-20 14:13:49.063 2 
2014-10-20 14:13:54.063 2 
2014-10-20 14:20:24.063 2 
2014-10-20 14:13:02.063 3 

複製一個類似的toybox表作爲在這個例子中,你可以使用下面的代碼:

declare @tmp as table(thedate datetime,ID int) 
insert into @tmp (thedate, ID) values 
    (dateadd(s,0,getdate()),1), (dateadd(s,1,getdate()),1), (dateadd(s,5,getdate()),1), 
    (dateadd(s,-52,getdate()),2), (dateadd(s,7,getdate()),2), (dateadd(s,12,getdate()),2),(dateadd(s,402,getdate()),2), 
    (dateadd(s,-40,getdate()),3) 

對於每個ID我想要兩個日期之間的平均時間。現在數據庫很大(每個ID都有大量的ID和日期),因此它必須非常高效。我想這樣的結果:

ID AvgTime (seconds) 
1 2,5 
2 151,333333333333 
3 NULL 

下面的代碼我想要做什麼,但它是太慢:

select 
    a.ID, 
    (select top 1 avg(cast(datediff(s,(select max(thedate) 
             from @tmp c where ID = b.ID 
              and thedate < b.thedate) 
            ,thedate) as float)) over (partition by b.ID) 
     from @tmp b where ID = a.ID) 
from @tmp a group by ID 

有誰知道如何有效地做到這一點?

回答

1

平均值是最大值減去最小值除以1後的值。你可以用它來寫一個相對簡單的查詢:

select id, 
     cast(datediff(second, min(thedate), max(thedate)) as float)/(count(*) - 1) 
from @tmp 
group by id; 

如果一些IDS的只有一行,那麼你會希望通過0到檢查潛在的鴻溝:

select id, 
     (case when count(*) > 1 
      then cast(datediff(second, min(thedate), max(thedate)) as float)/(count(*) - 1) 
     end) as AvgDiff 
from @tmp 
group by id; 
+0

這是有益的看看爲什麼這個工作 - 沒有在這裏重複,請參閱[這個答案](http://stackoverflow.com/a/5160040/4137916)一個密切相關的問題。 – 2014-10-20 13:12:31

+0

非常感謝 - 謝謝! – 2014-10-28 13:22:13