1

SQL Server 2012 に 2 つの列を持つテーブル UserActivity があるとします。

  • 活動日時
  • ユーザーID

30 日間にアクティビティがあった個別のユーザー数 (毎月のアクティブ ユーザー数) を毎日計算したいと考えています。(したがって、一度に 1 日ずつ増加する 30 日間のウィンドウがあります。SQL Server でウィンドウ関数を使用してこれを効率的に行うにはどうすればよいでしょうか?

出力は次のようになります。

Date,NumberActiveUsersInPrevious30Days
01-01-2010,13567
01-02-2010,14780
01-03-2010,13490
01-04-2010,15231
01-05-2010,15321
01-06-2010,14513
...
4

2 に答える 2

1

COUNT(DISTINCT ... ) OVER ()SQL Server は、または数値 ( 30 PRECEDING) と組み合わせて使用​​することをサポートしていませんRANGE

ウィンドウ関数にこれを強制しようとする気にはなりません。このCOUNT(DISTINCT UserID)要件により、各日付の 30 日間のウィンドウ全体を常に再検討する必要があります。

各日付の行を持つカレンダーテーブルを作成して使用できます

SELECT C.Date,
       NumberActiveUsersInPrevious30Days
FROM   Calendar C
       CROSS APPLY (SELECT COUNT(DISTINCT UserID)
                   FROM   UserActivity
                   WHERE  ActivityDateTime >= DATEADD(DAY, -30, C.[Date])
                   AND ActivityDateTime < C.[Date]) CA(NumberActiveUsersInPrevious30Days)
WHERE  C.Date BETWEEN '2010-01-01' AND '2010-01-06' 
于 2013-01-25T11:48:18.017 に答える
0

オプション 1: for (while) ループを毎日実行し、それぞれに 30 日さかのぼって選択します (明らかに非常に遅い)。

オプション 2:日ごとに 1 つの行を含む個別のテーブルを作成し、元のテーブルに結合します (これも非常に低速です)。

オプション 3:再帰的な CTE またはストアド プロシージャ (まだそれほど効果的ではありません)。

オプション 4:カーソルと組み合わせた for (while) ループ (効率的ですが、高度な SQL の知識が必要です)。このソリューションでは、各日と各行を順番にステップ実行し、平均を追跡します (日が範囲外になったときに減算する値を知るには、ある種のラップアラウンド配列が必要です)。

オプション 5:汎用/スクリプト プログラミング言語 (C++ / Java / PHP) でのオプション 3 (これらの言語のいずれかの基本的な知識があれば簡単に実行でき、効率的です)。

関連する いくつかの質問

于 2013-01-25T08:23:16.380 に答える