這是應該幫助的。例如,您可能必須努力弄清楚如何處理周邊界。
這個想法是將數據分解爲登錄和註銷。登錄發生在登錄後的登錄+秒秒以便輕鬆計算。每個登錄名的值爲+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