(比較的)単純なSQLクエリの作成で問題が発生しています(SQL Server 2012が使用されています)。特定のユーザーのために何かをカウントするデータベースがあります。したがって、2つのテーブルで構成される非常に単純なデータベース構造があります。
テーブルusers
:
PK_User, uniqueidentifier
ID, bigint
Username, nvarchar(128)
CreationTimestamp, datetime
テーブルdata
:
PK_Data, uniqueidentifier
FK_User, uniqueidentifier
FK_Reporter, uniqueidentifier
CreationTimestamp, datetime
現在、次のSQLステートメントを使用しています。
SELECT u.Username, COUNT(d.FK_User) AS 'Count', CAST(FLOOR(CAST(d.CreationTimestamp AS float)) AS datetime) AS 'Date'
FROM data d INNER JOIN users u ON u.PK_User = d.FK_User
GROUP BY CAST(FLOOR(CAST(d.CreationTimestamp AS float)) AS datetime), u.Username
ORDER BY CAST(FLOOR(CAST(d.CreationTimestamp AS float)) AS datetime)
これは次のようなものを提供します:
User1 5 %Date1%
User2 3 %Date1%
User1 7 %Date2%
User2 1 %Date2%
そのため、特定の日の各ユーザーの合計を取得できます。この合計を合計して、User1が2日目に5 + 7 = 12およびUser2 3 + 1 = 4を取得できるようにします。
どうすればこれを達成できますか?
「ウィンドウ」集約、つまり集約内のOVER
句が必要です。また、クエリにはすでに_GROUP BY
_が含まれているため、必要な集計は、すでに持っているSUM()
に対するCOUNT(d.FK_User)
です。
_SELECT
u.Username,
-- COUNT(d.FK_User) AS UserCount, -- if you need both counts
SUM(COUNT(d.FK_User)) OVER (PARTITION BY u.Username
ORDER BY CAST(d.CreationTimestamp AS DATE)
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW)
AS CumulativeUserCount,
CAST(d.CreationTimestamp AS DATE) AS CreationDate
FROM data d
INNER JOIN users u
ON u.PK_User = d.FK_User
GROUP BY
CAST(d.CreationTimestamp AS DATE), u.Username
ORDER BY
CreationDate ;
_
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
_は厳密には必要ありません。 OVER ()
内に_ORDER BY
_がある場合のウィンドウ集約のデフォルトフレームは_RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
_であり、ROWS
と同じ結果を生成しますが、準最適を生成する可能性があります実行計画。詳細については、 Aaron Bertrand のブログ記事 合計を実行するための最良のアプローチ– SQL Server 2012で更新 を参照してください。"Count"
_または角括弧_[Count]
_で引用することをお勧めします。