コマンド道場
集約関数のウィンドウ化難易度 ★★★★★

受注金額の累計を出す

取消されていない受注(status が 'done')を受注日の古い順に並べ、受注ごとの金額と、その受注までの累計金額を出してください。金額は 数量 × 単価 の合計です。列は「受注日, 受注番号, 金額, 累計」の順、受注日の古い順に並べてください。

この書き方が使えない製品があります そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server / Oracle Database

未確認: IBM Db2

製品ごとの対応表(実測)を見る

  • 集約関数に OVER を付けると、行をまとめずに集計値を各行へ付けられます。GROUP BY との違いはここです。
  • OVER (ORDER BY ...) を書くと、既定の枠は「先頭から現在行まで」になります。標準 SQL で決まっている既定です。
  • ウィンドウ関数が使えるのは SQLite 3.25 以降・MySQL 8.0 以降です。
● 起動中…

この問題で使えるテーブル(名前をタップすると入力できます)

10

NULL
🔑int不可
int不可
date不可
text不可
データを見る(先頭 5 行)
juchu_idkokyaku_idjuchu_onstatus
100112025-11-05done
100222025-11-18done
100312025-12-02done
100432025-12-09cancel
100542025-12-24done

17

NULL
🔑int不可
🔑int不可
int不可
int不可
numeric(10,0)不可
データを見る(先頭 5 行)
juchu_idgyo_noshohin_idsuryotanka
10011120180
10012230120
100214223800
100225118500
10031644200

5

NULL
🔑int不可
text不可
text
date不可
データを見る(先頭 5 行)
kokyaku_idkokyaku_nameprefcreated_on
1青葉工業東京都2024-05-10
2白樺物産大阪府2024-08-01
3黒松システム東京都2025-01-15
4赤坂商会NULL2025-03-20
5三田商事愛知県2025-06-01

7

NULL
🔑int不可
text不可
text不可
numeric(10,0)不可
データを見る(先頭 5 行)
shohin_idshohin_namecategoryprice
1ノート文具180
2ボールペン文具120
3付箋文具250
4デスクチェア家具24800
5書棚家具18500

解説

結論

累計は sum(列) OVER (ORDER BY 並び順) です。GROUP BY の sum と字面は同じですが、働きがまったく違います。

★GROUP BY の集約とウィンドウ関数の違い: GROUP BY の sum は、まとめた行を 1 行に減らします。ウィンドウ関数の sum は、行を減らさずに、各行の隣に計算結果を並べます。「明細を残したまま合計も見たい」という要求は、ウィンドウ関数でなければ表現できません。

★OVER の中の ORDER BY が累計を作ります: OVER () と書くと枠は全行になり、どの行にも同じ総合計が付きます。OVER (ORDER BY 日付) と書くと、枠の既定が「先頭から現在行まで」に変わり、結果として累計になります。ORDER BY を書いたか書かなかったかで意味が変わる、というのがここでの要点です。

★並び順が同じ値のときの注意: 受注日が同じ受注が 2 件あると、どちらを先に足すかが決まらず、累計の途中の値が変わりえます。OVER の ORDER BY には、重複しないキー(ここでは juchu_id)まで含めておくのが安全です。

★2 段構えが必要な理由

1 つの SELECT の中で GROUP BY の結果に対してウィンドウ関数を使うこともできますが(sum(sum(x)) OVER (...) と書けます)、読みにくくなります。派生表や WITH で「受注ごとの金額」という中間の表を作ってから累計を取る方が、意図が明確です。

よくある間違い

①OVER の中の ORDER BY を書き忘れて総合計になる。②GROUP BY のまとめる単位を間違え、受注が複数行に分かれる。③取消などの条件を 1 段目に書き忘れる。

根拠(一次情報)