这是应该帮助的。例如,您可能必须努力弄清楚如何处理周边界。
这个想法是将数据分解为登录和注销。登录发生在登录后的登录+秒秒以便轻松计算。每个登录名的值为+1
(并发用户数加1)。每个注销的值都是-1
。
该版本的查询使用相关的子查询来计算并发用户的数量和到下一个事件的时间。在SQL Server 2012中,这些可以用累加和来代替(sum() over (partition . . order by)
和lead()
。
最后一步是计算平均值,这需要考虑持续时间的准确性。它会怀念在开始阶段并没有结束登录为此,你可能需要用的0
到事件的值添加虚假记载CTE:
with d as (
select 1 as userid, CAST('2013-04-30 09:24:07.127' as datetime) as logint, 21456 as secs union all
select 2, CAST('2013-04-29 09:22:05.023' as datetime), 26477 union all
select 1 , CAST('2013-04-30 10:24:07.787' as datetime), 86543 union all
select 2, CAST('2013-04-30 12:55:55.846' as datetime), 32237 union all
select 1, CAST('2013-04-30 08:24:12.347' as datetime), 92231
),
events as (
select logint as thetime, 1 as loginp
from d
union all
select DATEADD(second, secs, logint), -1
from d
),
t as (
select e.*,
(select SUM(loginp) from events e2 where e2.thetime <= e.thetime) as concurrents,
(select top 1 thetime from events e2 where e2.thetime > e.thetime order by e2.thetime desc) as nexttime,
DATEDIFF(second, thetime, (select top 1 thetime from events e2 where e2.thetime > e.thetime order by e2.thetime desc)) as dur
from events e
)
select SUM(concurrents*1.0*dur)/SUM(dur) as avg_concurrents,
MIN(concurrents), MAX(concurrents)
from t
这是假定没有重复的时间 - 你没有办法区分问题中的重复,如果你有一个id,很容易就可以把它弄清楚下一步会发生什么,比使用时间。
如果你想做一段时间然后[this](http://stackoverflow.com/questions/12428873/avoiding-gaps-in-datetime-intervals-with-cte-and-start- and-end-datetimes/12504291#12504291)可能会有所帮助。尽管您可以总结所有时间的数据,但是它在数据库超过几年之后真的有意义吗? – HABO 2013-04-30 14:49:53
我只需要捕获一周或更新的数据。 – Hoopdady 2013-04-30 15:11:42
如果您正在尝试评估系统上的负载,我无法想象这些用户在登录后仍处于活动状态。 – JeffO 2013-04-30 15:45:54