コマンド道場

$ man sum-over

SUM() OVER(累計)

ウィンドウ関数

集約関数をウィンドウ関数として使う。ORDER BY を付けるかどうかで、累計か総計かが変わる。

呼び出しの形

SUM(式) OVER (ORDER BY 式)
SUM(式) OVER (PARTITION BY 式 ORDER BY 式)
SUM(式) OVER ()

つまずきやすいところ

  • ORDER BY の有無で総計と累計が入れ替わります。 書き忘れると、全行が同じ値(総計)になります。

  • 既定のフレームは RANGE なので、ORDER BY の値が同じ行はまとめて加算されます。1 行ずつ積みたいなら ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW と書いてください。

  • SUM(COUNT(*)) OVER (...) のように、集約の結果にウィンドウ関数を重ねられます。この場合ウィンドウ関数は GROUP BY の後に評価されます。

  • ROWS で 1 行ずつ積むときは、ORDER BY を一意になるまで書いてください。同値があると積む順番が決まらず、実行のたびに途中の値が変わりえます

実行例

結果は実際に流したものです。同じ SQL を 自由に打てる画面 で試すと、同じ結果になります。

累計と総計を並べて見る
SELECT juchu_on, COUNT(*) AS kensu, SUM(COUNT(*)) OVER (ORDER BY juchu_on) AS ruikei, SUM(COUNT(*)) OVER () AS soukei FROM juchu GROUP BY juchu_on ORDER BY juchu_on
juchu_onkensuruikeisoukei
2025-11-051110
2025-11-181210
2025-12-021310
2025-12-091410
2025-12-241510
2026-01-071610
2026-01-211710
2026-02-031810

10(うち 8 行を表示)

ORDER BY を書いた列だけが累計になります。書かない側はどの行でも同じ値です。

受注ごとに累計を取り直す
SELECT juchu_id, gyo_no, suryo, SUM(suryo) OVER (PARTITION BY juchu_id ORDER BY gyo_no) AS juchu_nai_ruikei FROM juchu_meisai ORDER BY juchu_id, gyo_no
juchu_idgyo_nosuryojuchu_nai_ruikei
100112020
100123050
1002122
1002213
1003144
1003226
1004155
100511010

17(うち 8 行を表示)

同じ値が並ぶと、既定のフレームではまとめて加算される
SELECT shohin_id, juchu_id, gyo_no, suryo, SUM(suryo) OVER (ORDER BY shohin_id) AS range_de_matomete, SUM(suryo) OVER (ORDER BY shohin_id, juchu_id, gyo_no ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS rows_de_ichigyou_zutsu FROM juchu_meisai ORDER BY shohin_id, juchu_id, gyo_no
shohin_idjuchu_idgyo_nosuryorange_de_matometerows_de_ichigyou_zutsu
110011208020
110051108030
110081508080
21001230152110
2100520152110
21006130152140
21010212152152
4100212160154

17(うち 8 行を表示)

shohin_id が同じ行は、既定(RANGE)では一度に足されるので同じ値が続きます。右の列は ROWS を明示し、並びも一意にしてあるので 1 行ずつ増えます。

説明

SUM などの集約関数は OVER を付けると行をまとめずに計算できます。元の行を残したまま、合計や累計を横に並べられます。

⚠️ ORDER BY を書くかどうかで意味がまるで変わります。

  • SUM(x) OVER () … 全体の総計。どの行でも同じ値
  • SUM(x) OVER (ORDER BY d)先頭からその行までの累計

これは、ORDER BY を書くとフレームの既定が「最初から現在行まで」に変わるためです。書き忘れると総計、書いたつもりで並び順が曖昧だと累計がずれる——どちらも起きます。

⚠️ さらに落とし穴があります。既定のフレームは RANGE なので、ORDER BY の値が同じ行は、まとめて一度に加算されます。1 行ずつ積み上げたいなら ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW と明示してください。

ほかの製品でも通るか

未確認の製品があります そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server / Oracle Database

未確認: IBM Db2

製品ごとの対応表(根拠つき)を見る

次に読む

関係する関数

根拠にした一次情報