web-dev-qa-db-ja.com

累積合計のSQLクエリ

(比較的)単純な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を取得できるようにします。

どうすればこれを達成できますか?

5
Roland

「ウィンドウ」集約、つまり集約内の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]_で引用することをお勧めします。
9
ypercubeᵀᴹ