0

さまざまな目的でさまざまな時間に数千人のユーザーがログインするアプリケーションがあります。ここでのタスクは、"ピーク時のユーザー数" をどうにかして把握することです。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 に答える