Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. SQL Dictionary
  3. SUM / AVG (Window)

SUM / AVG (Window)

Since: SQL:2003(2003)

SUM and AVG used as window functions can calculate running totals, moving averages, and rolling sums without grouping rows. Combined with a frame clause, you can precisely control which rows are included in the calculation.

Syntax

Running total (from the first row to the current row).

SUM(column) OVER (
    [PARTITION BY partition_column]
    ORDER BY order_column
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
)

Moving average over the last N rows.

AVG(column) OVER (
    ORDER BY order_column
    ROWS BETWEEN N PRECEDING AND CURRENT ROW
)

Grand total (no frame clause, no PARTITION BY).

SUM(column) OVER ()

Syntax Reference

Frame clauseDescription
UNBOUNDED PRECEDINGThe first row of the window (or partition).
CURRENT ROWThe current row.
UNBOUNDED FOLLOWINGThe last row of the window (or partition).
N PRECEDINGN rows before the current row.
N FOLLOWINGN rows after the current row.

Sample Code

The following examples use the daily_sales table.

daily_sales order_date amount 2024-01-01 120000 2024-01-02 85000 2024-01-03 230000 2024-01-04 98000 4 rows in set

Calculate the running total of sales by order date and its percentage of the grand total.

sample_sum_avg_window.sql
SELECT
    order_date,
    amount,
    SUM(amount) OVER (
        ORDER BY order_date
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS running_total,
    SUM(amount) OVER () AS grand_total,
    ROUND(
        amount * 100.0 / SUM(amount) OVER (), 1
    ) AS pct_of_total
FROM daily_sales
ORDER BY order_date;
+------------+--------+---------------+-------------+--------------+
| order_date | amount | running_total | grand_total | pct_of_total |
+------------+--------+---------------+-------------+--------------+
| 2024-01-01 | 120000 |        120000 |      533000 |         22.5 |
| 2024-01-02 |  85000 |        205000 |      533000 |         15.9 |
| 2024-01-03 | 230000 |        435000 |      533000 |         43.2 |
| 2024-01-04 |  98000 |        533000 |      533000 |         18.4 |
+------------+--------+---------------+-------------+--------------+
4 rows in set

Calculate the 3-day moving average of sales.

sample_sum_avg_window.sql
SELECT
    order_date,
    amount,
    AVG(amount) OVER (
        ORDER BY order_date
        ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
    ) AS moving_avg_3d
FROM daily_sales
ORDER BY order_date;
+------------+--------+---------------+
| order_date | amount | moving_avg_3d |
+------------+--------+---------------+
| 2024-01-01 | 120000 |   120000.0000 |
| 2024-01-02 |  85000 |   102500.0000 |
| 2024-01-03 | 230000 |   145000.0000 |
| 2024-01-04 |  98000 |   137666.6667 |
+------------+--------+---------------+
4 rows in set

Calculate the 2-day rolling sum of sales.

sample_sum_avg_window.sql
SELECT
    order_date,
    amount,
    SUM(amount) OVER (
        ORDER BY order_date
        ROWS BETWEEN 1 PRECEDING AND CURRENT ROW
    ) AS moving_sum_2d
FROM daily_sales
ORDER BY order_date;
+------------+--------+---------------+
| order_date | amount | moving_sum_2d |
+------------+--------+---------------+
| 2024-01-01 | 120000 |        120000 |
| 2024-01-02 |  85000 |        205000 |
| 2024-01-03 | 230000 |        315000 |
| 2024-01-04 |  98000 |        328000 |
+------------+--------+---------------+
4 rows in set

Database Compatibility

Window function syntax for SUM() and AVG() with frame clauses is supported in MySQL (8.0+), PostgreSQL, Oracle, SQL Server, and SQLite (3.25+).

SELECT
    order_date,
    amount,
    SUM(amount) OVER (
        ORDER BY order_date
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS running_total
FROM daily_sales
ORDER BY order_date;

Notes

SUM and AVG as window functions add aggregate values to each row without reducing the number of rows. The key is to use the frame clause to specify which rows are included in the calculation.

If you specify ORDER BY but omit the frame clause, the default frame is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW. Rows with the same ORDER BY value are all treated as the "current row," which can produce unexpected results. Make it a habit to always specify ROWS BETWEEN explicitly. When in doubt, use ROWS.

For the basic window function syntax, see OVER / PARTITION BY. For referencing previous or next rows, see LAG / LEAD.

If you find any errors or copyright issues, please .