さまざまな目的でさまざまな時間に数千人のユーザーがログインするアプリケーションがあります。ここでのタスクは、"ピーク時のユーザー数" をどうにかして把握することです。SQL に記録するのは userLoginTime,timespent です。ここでの問題は
アプリのピーク時間を実際に計算する方法。ピーク時の利用者数の計算方法。
Sqlで可能ですか
さまざまな目的でさまざまな時間に数千人のユーザーがログインするアプリケーションがあります。ここでのタスクは、"ピーク時のユーザー数" をどうにかして把握することです。SQL に記録するのは userLoginTime,timespent です。ここでの問題は
アプリのピーク時間を実際に計算する方法。ピーク時の利用者数の計算方法。
Sqlで可能ですか
私は遊んだことがあります-私は記録された開始値と終了datetime2
値を持つセッションで作業していますが、うまくいけば、これに準拠するように現在のデータを適応させることができます:
サンプルデータ(答えが間違っている場合は、これを採用して質問に追加し、さらにサンプルと期待される出力を追加できます):
create table #Sessions (
--We'll treat this as a semi-open interval - the session was "live" at SessionStart, and "dead" at SessionEnd
SessionStart datetime2 not null,
SessionEnd datetime2 null
)
insert into #Sessions (SessionStart,SessionEnd) values
('20120101','20120105'),
('20120103','20120109'),
('20120107','20120108')
そしてクエリ:
--Logically, the highest number of simultaneous users was reached at some point when a session started
;with StartTimes as (
select distinct SessionStart as Instant from #Sessions
), Overlaps as (
select
st.Instant,COUNT(*) as Cnt,MIN(s.SessionEnd) as SessionEnd
from
StartTimes st
inner join
#Sessions s
on
st.Instant >= s.SessionStart and
st.Instant < s.SessionEnd
group by
st.Instant
), RankedOverlaps as (
select Instant as SessionStart,Cnt,SessionEnd,RANK() OVER (ORDER BY Cnt desc) as rnk
from Overlaps
)
select * from RankedOverlaps where rnk = 1
drop table #Sessions
これは、私のサンプルデータで次のようになります。
SessionStart Cnt SessionEnd rnk
---------------------- ----------- ---------------------- --------------------
2012-01-03 00:00:00.00 2 2012-01-05 00:00:00.00 1
2012-01-07 00:00:00.00 2 2012-01-08 00:00:00.00 1
上記を引き続き使用しますが、「ピークではない」値も分析する場合の代替アプローチは、次のとおりです。
--An alternate approach - arrange all of the distinct time values from Sessions into order
;with Instants as (
select SessionStart as Instant from #Sessions
union --We want distinct here
select SessionEnd from #Sessions
), OrderedInstants as (
select Instant,ROW_NUMBER() OVER (ORDER BY Instant) as rn
from Instants
), Intervals as (
select oi1.Instant as StartTime,oi2.Instant as EndTime
from
OrderedInstants oi1
inner join
OrderedInstants oi2
on
oi1.rn = oi2.rn - 1
), IntervalOverlaps as (
select
StartTime,
EndTime,
COUNT(*) as Cnt
from
Intervals i
inner join
#Sessions s
on
i.StartTime < s.SessionEnd and
s.SessionStart < i.EndTime
group by
StartTime,
EndTime
)
select * from IntervalOverlaps order by Cnt desc,StartTime
今回は、すべての期間と、その時点での同時ユーザー数(高いものから低いものへの順序)を出力しています。
StartTime EndTime Cnt
---------------------- ---------------------- -----------
2012-01-03 00:00:00.00 2012-01-05 00:00:00.00 2
2012-01-07 00:00:00.00 2012-01-08 00:00:00.00 2
2012-01-01 00:00:00.00 2012-01-03 00:00:00.00 1
2012-01-05 00:00:00.00 2012-01-07 00:00:00.00 1
2012-01-08 00:00:00.00 2012-01-09 00:00:00.00 1