WITH(共通テーブル式)を使って集計する
WITH句とは
共通テーブル式 (CTE) は、単一の SELECT、INSERT、UPDATE、DELETE、CREATE VIEW の各ステートメントの実行スコープ内で定義される一時結果セットと考えることができます。CTE は、オブジェクトとして格納されず、クエリが実行されている間しか保持されない点で、派生テーブルに似ています。派生テーブルと異なるのは、CTE では自己参照が可能であり、同じクエリ内で複数回参照が可能なことです。
イメージとしては、サブクエリに名前を付け一時テーブルとして扱い、クエリ内から参照可能としたもの。
使い方
下記のような売上データがあるとします。
No | 日付 | 商品 | 売上金額 |
---|---|---|---|
1 | 2014-10-01 | 鉛筆 | 100 |
2 | 2014-10-01 | 消しゴム | 50 |
3 | 2014-10-02 | ボールペン | 150 |
4 | 2014-10-04 | 鉛筆 | 100 |
5 | 2014-10-04 | ボールペン | 150 |
日別の商品売上金額を集計するには下記のクエリで集計できます。
SELECT 日付, SUM(売上金額) AS 計 FROM 売上データ GROUP BY 日付
日付 | 計 |
---|---|
2014-10-01 | 150 |
2014-10-02 | 150 |
2014-10-04 | 250 |
上記の場合は、売上レコードが存在する日のみ集計されますが、 売上が存在しない日も含めて集計したい場合には、WITH句を使って集計します。
最初に一時テーブルとして対象範囲のカレンダーを作成し、 一時テーブルに対して集計データを結合する下記のクエリで集計できます。
DECLARE @DateFrom DATE = '2014-10-01'; DECLARE @DateTo DATE = '2014-10-05'; WITH DateTable (MyDate) AS ( SELECT @DateFrom UNION ALL SELECT DATEADD(dd, 1, MyDate) FROM DateTable WHERE MyDate < @DateTo ) SELECT DT.MyDate AS 日付, ISNULL(T.計, 0) AS 計 FROM DateTable DT LEFT JOIN ( SELECT 日付, SUM(売上金額) AS 計 FROM 売上データ GROUP BY 日付 ) T ON DT.MyDate = T.日付 OPTION (MAXRECURSION 0);
日付 | 計 |
---|---|
2014-10-01 | 150 |
2014-10-02 | 150 |
2014-10-03 | 0 |
2014-10-04 | 250 |
2014-10-05 | 0 |