假设我有一个这样的表:
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
有谁知道如何有效地做到这一点?
答案 0 :(得分:1)
平均值是最大值减去最小值除以计数值的1。您可以使用它来编写一个相对简单的查询:
select id,
cast(datediff(second, min(thedate), max(thedate)) as float) / (count(*) - 1)
from @tmp
group by id;
如果某些ID只有一行,那么您想要检查可能的除以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;