Reputation: 3281
I have a application which has 1000's of users logging into at various times for various purposes. the task now is to somehow figure out "number of users at peak time" what we record in sql is userLoginTime,timespent. the problem here is
How to actually calculate peak time for the app. and how to calculate number of users at peak time.
Is it possible in Sql
Upvotes: 0
Views: 913
Reputation: 239764
I've had a play around - I'm working with sessions with a recorded start and end datetime2
values, but hopefully you can adapt your current data to conform to this:
Sample data (if I've got the answer wrong, maybe you can adopt this, add it to your question, and add more samples and expected outputs):
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')
And the query:
--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
Which, with my sample data gives:
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 alternative approach, still using the above, but if you also want to analyze "not quite peak" values also, is as follows:
--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
This time, I'm outputting all of the time periods, together with the number of simultaneous users at the time (order from highest to lowest):
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
Upvotes: 2