0

我有一个应用程序,它有 1000 名用户在不同时间出于各种目的登录。现在的任务是以某种方式找出“高峰时间的用户数”,我们在 sql 中记录的是 userLoginTime,timespent。这里的问题是

如何实际计算应用程序的高峰时间。以及如何计算高峰期的用户数。

是否可以在 Sql 中

4

1 回答 1

2

我玩过 - 我正在处理带有记录的开始和结束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
于 2012-06-20T12:49:11.230 回答