Xorthax had totals for each customer—but something still felt off. He couldn’t tell what happened first, what came next, or how values changed over time.
To make window functions more useful, he needed order.
ORDER BY inside a window function controls the sequence of rows.
FUNCTION(...) OVER (
PARTITION BY column
ORDER BY column
)
This tells SQL:
| OrderID | CustomerID | OrderDate | Amount |
|---|---|---|---|
| 1 | A | 2024-01-10 | 200 |
| 2 | A | 2024-01-01 | 100 |
| 3 | A | 2024-01-05 | 150 |
SELECT OrderID, OrderDate, Amount,
SUM(Amount) OVER (
PARTITION BY CustomerID
ORDER BY OrderDate
) AS Value
FROM Orders;
Result:
| OrderID | OrderDate | Amount | Value |
|---|---|---|---|
| 2 | 2024-01-01 | 100 | 100 |
| 3 | 2024-01-05 | 150 | 250 |
| 1 | 2024-01-10 | 200 | 450 |
Notice how adding order by changes the result.
PARTITION BY CustomerID creates a group for each customer.
ORDER BY OrderDate arranges rows from earliest to latest.
The function processes rows in that order—one step at a time.
For each order, calculate a running total of totalamount across all orders, ordered by orderdate.
| Column | Type |
|---|---|
| orderid | bigint |
| customerid | bigint |
| orderdate | timestamp without time zone |
| totalamount | double precision |
| status | text |
| Column |
|---|
| orderid |
| orderdate |
| totalamount |
| running_total |
Right now, the function processes rows in order—but it still considers all previous rows.
Next, you’ll learn how to control exactly which rows are included in each calculation.