年月ごとの受注件数と売上
取消されていない受注(status が 'done')を年月ごとに集計してください。列は「年, 月, 受注件数, 売上合計」の順です。受注件数は受注の件数(明細の行数ではありません)、売上合計は 数量 × 単価 の合計です。年、月の順に古いものから並べてください。
この書き方が使えない製品があります そのまま使える: PostgreSQL / MySQL / MariaDB / Oracle Database
- SQLite では使えません(EXTRACT(日付の一部を取り出す))
- SQL Server では使えません(EXTRACT(日付の一部を取り出す))
未確認: IBM Db2
- EXTRACT(YEAR FROM 日付) が使えない製品があります。SQLite では strftime('%Y', 日付)、SQL Server では YEAR(日付) または DATEPART(year, 日付) と書きます。
- 日付の扱いは製品差がもっとも大きい領域です。年や月を取り出すときは、まず手元の製品での関数名を確かめてください。
この問題で使えるテーブル(名前をタップすると入力できます)
10 行
| 列 | 型 | NULL |
|---|---|---|
| 🔑 | int | 不可 |
| int | 不可 | |
| date | 不可 | |
| text | 不可 |
データを見る(先頭 5 行)
| juchu_id | kokyaku_id | juchu_on | status |
|---|---|---|---|
| 1001 | 1 | 2025-11-05 | done |
| 1002 | 2 | 2025-11-18 | done |
| 1003 | 1 | 2025-12-02 | done |
| 1004 | 3 | 2025-12-09 | cancel |
| 1005 | 4 | 2025-12-24 | done |
17 行
| 列 | 型 | NULL |
|---|---|---|
| 🔑 | int | 不可 |
| 🔑 | int | 不可 |
| int | 不可 | |
| int | 不可 | |
| numeric(10,0) | 不可 |
データを見る(先頭 5 行)
| juchu_id | gyo_no | shohin_id | suryo | tanka |
|---|---|---|---|---|
| 1001 | 1 | 1 | 20 | 180 |
| 1001 | 2 | 2 | 30 | 120 |
| 1002 | 1 | 4 | 2 | 23800 |
| 1002 | 2 | 5 | 1 | 18500 |
| 1003 | 1 | 6 | 4 | 4200 |
5 行
| 列 | 型 | NULL |
|---|---|---|
| 🔑 | int | 不可 |
| text | 不可 | |
| text | 可 | |
| date | 不可 |
データを見る(先頭 5 行)
| kokyaku_id | kokyaku_name | pref | created_on |
|---|---|---|---|
| 1 | 青葉工業 | 東京都 | 2024-05-10 |
| 2 | 白樺物産 | 大阪府 | 2024-08-01 |
| 3 | 黒松システム | 東京都 | 2025-01-15 |
| 4 | 赤坂商会 | NULL | 2025-03-20 |
| 5 | 三田商事 | 愛知県 | 2025-06-01 |
7 行
| 列 | 型 | NULL |
|---|---|---|
| 🔑 | int | 不可 |
| text | 不可 | |
| text | 不可 | |
| numeric(10,0) | 不可 |
データを見る(先頭 5 行)
| shohin_id | shohin_name | category | price |
|---|---|---|---|
| 1 | ノート | 文具 | 180 |
| 2 | ボールペン | 文具 | 120 |
| 3 | 付箋 | 文具 | 250 |
| 4 | デスクチェア | 家具 | 24800 |
| 5 | 書棚 | 家具 | 18500 |
解説
結論
EXTRACT(YEAR FROM 列) / EXTRACT(MONTH FROM 列) で年と月を取り出し、その 2 つで GROUP BY します。
★年でまとめずに月だけでまとめると、2025 年 2 月と 2026 年 2 月が 1 行に混ざります。このデータは 4 か月にまたがっているので、年をまとめのキーに入れたかどうかが結果に現れます。月次の集計で年を入れ忘れるのは実務でも起きる事故です。
★件数の数え方
juchu と juchu_meisai を結合した時点で、明細が 2 行ある受注は 2 行になります。この状態で count(*) を書くと明細の行数を数えることになり、「受注件数」ではありません。受注の件数を数えたいなら count(DISTINCT juchu_id) です。一方、売上は明細ごとの金額を足したいので sum のままで正しくなります。「結合したことで何が増えたか」を意識してください。
★どの単価を使うか
このデータでは、明細の tanka(受注時点の単価)と shohin.price(現在の定価)がわざと食い違っています。売上のように「そのとき実際にいくらだったか」を知りたい集計では、受注時点の単価を使います。マスタの定価を使うと、値上げや値引きのぶんだけ過去の売上が書き換わってしまいます。
⚠️ 日付関数は製品差が大きい領域です。EXTRACT は標準 SQL の書き方ですが、SQLite と SQL Server では使えません(実測)。移植の可能性がある処理では、日付の加工をアプリケーション側に寄せる、という判断もあります。
よくある間違い
①count(*) で明細の行数を数える。②年をまとめのキーに入れ忘れる。③GROUP BY に書く式と SELECT に書く式が食い違ってエラーになる。
根拠(一次情報)
- PostgreSQL 18 マニュアル: 日付/時刻関数と演算子(EXTRACT)一次情報・確認 2026-07-28
- PostgreSQL 18 マニュアル: 集約関数(count DISTINCT)一次情報・確認 2026-07-28