0

アプリケーションへのユーザー アクセス ログのテーブルがあります。サンプルデータは次のとおりです。

userid    |          login          | duration (seconds)
--------------------------------------------------------
1         | 2013-04-30 09:24:07.127 | 21456     
2         | 2013-04-29 09:22:05.023 | 26477     
1         | 2013-04-30 10:24:07.787 | 86543    
2         | 2013-04-30 12:55:55.846 | 32237    
1         | 2013-04-30 08:24:12.347 | 92231     

私の目標は、このデータからいくつかの指標を取得することです。過去 1 週間の最小、最大、および平均の同時ログイン ユーザーを取得する必要があります。誰かがより良いアイデアを持っていない限り、同時接続の意味のある平均を取得するには、間隔を選択する必要があると思います. 私が間違っている場合は修正してください。もしそうなら、私はそれで問題を抱えるべきではないと思います。問題を引き起こしているのはその最小値と最大値です。私はSQLでこれをやろうとしていますが、役に立ちません。問題は、接続間のオーバーラップをどのように測定するかを理解しようとしています。これを引き出してPythonで実行する必要があります。100,000 行以上あるので、少し面倒かもしれませんが、レポートを生成する必要があるのは 1 日に 1 回だけなので、効率は私の最大の関心事ではありません。

申し訳ありませんが、サンプル コードがありません。ここから始める方法がよくわかりません。助けてくれてありがとう。

4

1 に答える 1

0

ここに役立つものがあります。たとえば、週の境界をどうするかを考えなければならないでしょう。

アイデアは、データをログインとログアウトに分割することです。ログアウトは、ログインから login + secs 秒後に発生するため、簡単に計算できます。ログインごとに値が取得されます+1(同時ユーザー数に 1 が加算されます)。各ログアウトは の値を取得します-1

このバージョンのクエリは、相関サブクエリを使用して、同時ユーザー数と次のイベントまでの時間を把握します。SQL Server 2012 では、これらは累積合計 (sum() over (partition . . order by)およびlead().

最後のステップは、平均を計算することです。これを正確にするには、期間を考慮する必要があります。ただし、これは 100% 正確ではありません。最初と最後にピリオドがなく、ログインがないためです。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 を持っている場合は、時間を使用するのではなく、それを組み込んで次に何が起こるかを把握するのは簡単です。

于 2013-04-30T15:01:10.317 に答える