月次集計 — 日付を年月にまとめる

中級123

日次の売上テーブルから月ごとの売上を出します。strftime で年月を取り出し、GROUP BY でまとめる、レポートの一番の基本を練習します。

使うのは 90 日分の売上データ

このコースでは daily_sales テーブルを使います。 これまでの orders (12 行) と違い、

2026-01-01 から 2026-03-31 までの 90 日 ・ 2 店舗 ・ 563 行 が入っています。

中身
INLINE2売れた日 (2026-01-15 の形の文字列)
INLINE4東京本店 / 大阪支店
INLINE5INLINE6 の id
INLINE7売れた数
INLINE8売上金額 (単価 × 数量)

まず 1 行見てみましょう。

SELECT * FROM daily_sales LIMIT 5;

日付から年月を取り出す — strftime

日次のままでは行が多すぎて傾向が読めません。 月でまとめるのが第一歩です。

SQLite では strftime で日付の一部を取り出します。

SELECT sale_date, strftime('%Y-%m', sale_date) AS month FROM daily_sales LIMIT 3;

- %Y … 年 (2026)

- %m … 月 (01〜12。 1 桁の月も 0 埋めされる)

- %d … 日

- %w … 曜日 (0=日曜)

'%Y-%m' とつなげて書けば 2026-01 という文字列が返ります。

月ごとに合計する

取り出した年月で GROUP BY します。

SELECT strftime('%Y-%m', sale_date) AS month,
       SUM(amount) AS sales
FROM daily_sales
GROUP BY month
ORDER BY month;

これで 3 行 (1月・2月・3月) に畳まれます。 GROUP BY に別名 (month) をそのまま

書けるのは SQLite の親切な仕様で、 SELECT で付けた別名を GROUP BY / ORDER BY から

参照できます。 他のデータベースでは GROUP BY strftime('%Y-%m', sale_date)

式をもう一度書く必要があることも多いので、 覚えておくと移植のときに困りません。

件数と平均も一緒に出す

合計だけ見ていると 「売れた金額は増えたが、 取引の数は減っている」 のような

中身の変化を見落とします。 合計 ・ 件数 ・ 平均は 3 点セットで出します。

SELECT strftime('%Y-%m', sale_date) AS month,
       SUM(amount)   AS sales,
       COUNT(*)      AS lines,
       ROUND(AVG(amount)) AS avg_line
FROM daily_sales
GROUP BY month
ORDER BY month;

COUNT(*) は明細の行数です。 「何日分あるか」 を数えたいなら

COUNT(DISTINCT sale_date) と書きます。 数えたい単位が行なのか日なのかを

必ず言葉にしてから書くと間違えません。

並べ替えは文字列のままでうまくいく

2026-01 2026-02 2026-03文字列として並べても時系列と一致します

年 4 桁 ・ 月 2 桁 のゼロ埋めが効いているためです。

逆に 2026-1 のように 0 埋めしない形にすると 2026-102026-2 より

前に来てしまいます。 日付を文字列で扱うときは桁を揃えるのが鉄則です。

よくあるつまずき

- GROUP BY を書き忘れて 1 行だけ返る — 集計関数だけを書くと全体の合計になります。

「月ごと」 と言った時点で GROUP BY が要ります。

- WHERE で月を絞ろうとして効かないWHERE month = '2026-01' は書けません。

WHERE は GROUP BY より先に評価されるので、 別名はまだ存在しません。

WHERE sale_date >= '2026-01-01' AND sale_date < '2026-02-01' のように

元の列で絞るか、 集計後に絞るなら HAVING を使います。

- AVG(amount) が思ったより小さい — 明細 1 行あたりの平均です。

1 日あたりの平均が欲しいなら SUM(amount) / COUNT(DISTINCT sale_date) です。

実務での使いどころ

月次レポートは 「まず出す」 の定番です。 ここで出した 3 列 (合計 ・ 件数 ・ 平均) が

そのまま 「売れたのは単価が上がったからか、 数が出たからか」 の答えになります。

次のレッスン: 曜日別集計 — 合計ではなく平均で比べる

データベースを初期化中...
SQL エディタCtrl+Enter で実行
SQL を入力して実行してください
練習問題 — 0/3 完了 (0/80pt)
daily_sales から月ごとの売上合計を出してください。列は month (2026-01 の形) と sales の 2 つ、月の昇順で並べます。
25pt
月ごと・店舗ごとの売上合計を出してください。列は month・store・sales の 3 つ、month → store の順で並べます。
25pt
月ごとに、売上合計 sales・明細の件数 lines・売上のあった日数 days を出してください。列は month・sales・lines・days、月の昇順です。
30pt