SQL Window Function Running Totals
Use PostgreSQL window functions with explicit ROWS frames to compute running totals, moving averages, and each day's share of an account.
Code
-- Schema assumptions (PostgreSQL 15+):
-- payments(id bigint PRIMARY KEY, account_id bigint NOT NULL,
-- paid_at date NOT NULL, amount_cents integer NOT NULL CHECK (amount_cents > 0))
-- The TEMP table mirrors that shape so the query runs in a scratch database.
CREATE TEMP TABLE payments (
id bigint PRIMARY KEY,
account_id bigint NOT NULL,
paid_at date NOT NULL,
amount_cents integer NOT NULL CHECK (amount_cents > 0)
);
INSERT INTO payments (id, account_id, paid_at, amount_cents) VALUES
(1, 10, DATE '2026-10-01', 1200),
(2, 10, DATE '2026-10-02', 800),
(3, 10, DATE '2026-10-04', 1500),
(4, 20, DATE '2026-10-01', 500),
(5, 20, DATE '2026-10-03', 700),
(6, 20, DATE '2026-10-03', 300);
WITH daily AS (
SELECT account_id, paid_at, SUM(amount_cents) AS day_cents
FROM payments
GROUP BY account_id, paid_at
)
SELECT
account_id,
paid_at,
day_cents,
SUM(day_cents) OVER (
PARTITION BY account_id
ORDER BY paid_at
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_total_cents,
ROUND(AVG(day_cents) OVER (
PARTITION BY account_id
ORDER BY paid_at
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
), 2) AS moving_avg_cents,
ROUND(100.0 * day_cents / SUM(day_cents) OVER (PARTITION BY account_id), 2) AS pct_of_account
FROM daily
ORDER BY account_id, paid_at;Report a problem with this exampleOpens a pre-filled issue on GitHub.