runtime
37 / 88

lesson 37 Window functions · advanced

Running totals

Add values progressively in a defined order.

the idea

SUM(amount) OVER (ORDER BY … ROWS UNBOUNDED PRECEDING) accumulates a running total row by row. PARTITION BY restarts it for each account or period. Adding the opening balance turns cumulative movements into a running balance.

Dataset: Finance / Payments

The tables the challenges use, with their first 6 rows. Under each column name: the kind of value it holds, and which table it links to.

accounts7 columns · 2,109 rows
account_idnumber · unique idcustomer_idnumber · links to customersaccount_typetextopened_atdateclosed_attextcredit_limit_centsnumberopening_balance_centsnumber
11checking2022-02-24NULLNULL43125
22checking2025-06-11NULLNULL0
33checking2024-07-07NULLNULL216925
43savings2024-10-07NULLNULL475941
53credit_card2024-09-26NULL1020600-339148
64checking2023-07-18NULLNULL155995
account_idnumber · unique id
1
customer_idnumber · links to customers
1
account_typetext
checking
opened_atdate
2022-02-24
closed_attext
NULL
credit_limit_centsnumber
NULL
opening_balance_centsnumber
43125
account_idnumber · unique id
2
customer_idnumber · links to customers
2
account_typetext
checking
opened_atdate
2025-06-11
closed_attext
NULL
credit_limit_centsnumber
NULL
opening_balance_centsnumber
0
account_idnumber · unique id
3
customer_idnumber · links to customers
3
account_typetext
checking
opened_atdate
2024-07-07
closed_attext
NULL
credit_limit_centsnumber
NULL
opening_balance_centsnumber
216925
account_idnumber · unique id
4
customer_idnumber · links to customers
3
account_typetext
savings
opened_atdate
2024-10-07
closed_attext
NULL
credit_limit_centsnumber
NULL
opening_balance_centsnumber
475941
account_idnumber · unique id
5
customer_idnumber · links to customers
3
account_typetext
credit_card
opened_atdate
2024-09-26
closed_attext
NULL
credit_limit_centsnumber
1020600
opening_balance_centsnumber
-339148
account_idnumber · unique id
6
customer_idnumber · links to customers
4
account_typetext
checking
opened_atdate
2023-07-18
closed_attext
NULL
credit_limit_centsnumber
NULL
opening_balance_centsnumber
155995

first 6 of 2,109 rows · your queries use all of them

transactions12 columns · 84,798 rows
transaction_idnumber · unique idaccount_idnumber · links to accountstransaction_typetextstatustextamount_centsnumberinitiated_atdate & timeposted_atdate & timedescriptiontextmerchant_idnumber · links to merchantsauthorization_idnumber · links to authorizationsrefund_idnumber · links to refundschargeback_idnumber · links to chargebacks
1103card_purchaseposted-13992025-01-01 04:00:002025-01-02 06:23:00TRUE STREAMING #7119591980NULLNULL
2377card_purchaseposted-39992025-01-01 04:00:002025-01-03 10:26:00VISTA GYM #1969656710NULLNULL
3442card_purchaseposted-6992025-01-01 04:00:002025-01-03 04:21:00WILLOW STREAMING #8179557848NULLNULL
4447card_purchaseposted-49992025-01-01 04:00:002025-01-02 12:31:00OAK GYM #9649697931NULLNULL
5450card_purchaseposted-24992025-01-01 04:00:002025-01-02 08:01:00BIRCH GYM #4989688096NULLNULL
6497card_purchaseposted-8992025-01-01 04:00:002025-01-02 12:11:00VERDE STREAMING #3859588870NULLNULL
transaction_idnumber · unique id
1
account_idnumber · links to accounts
103
transaction_typetext
card_purchase
statustext
posted
amount_centsnumber
-1399
initiated_atdate & time
2025-01-01 04:00:00
posted_atdate & time
2025-01-02 06:23:00
descriptiontext
TRUE STREAMING #711
merchant_idnumber · links to merchants
959
authorization_idnumber · links to authorizations
1980
refund_idnumber · links to refunds
NULL
chargeback_idnumber · links to chargebacks
NULL
transaction_idnumber · unique id
2
account_idnumber · links to accounts
377
transaction_typetext
card_purchase
statustext
posted
amount_centsnumber
-3999
initiated_atdate & time
2025-01-01 04:00:00
posted_atdate & time
2025-01-03 10:26:00
descriptiontext
VISTA GYM #196
merchant_idnumber · links to merchants
965
authorization_idnumber · links to authorizations
6710
refund_idnumber · links to refunds
NULL
chargeback_idnumber · links to chargebacks
NULL
transaction_idnumber · unique id
3
account_idnumber · links to accounts
442
transaction_typetext
card_purchase
statustext
posted
amount_centsnumber
-699
initiated_atdate & time
2025-01-01 04:00:00
posted_atdate & time
2025-01-03 04:21:00
descriptiontext
WILLOW STREAMING #817
merchant_idnumber · links to merchants
955
authorization_idnumber · links to authorizations
7848
refund_idnumber · links to refunds
NULL
chargeback_idnumber · links to chargebacks
NULL
transaction_idnumber · unique id
4
account_idnumber · links to accounts
447
transaction_typetext
card_purchase
statustext
posted
amount_centsnumber
-4999
initiated_atdate & time
2025-01-01 04:00:00
posted_atdate & time
2025-01-02 12:31:00
descriptiontext
OAK GYM #964
merchant_idnumber · links to merchants
969
authorization_idnumber · links to authorizations
7931
refund_idnumber · links to refunds
NULL
chargeback_idnumber · links to chargebacks
NULL
transaction_idnumber · unique id
5
account_idnumber · links to accounts
450
transaction_typetext
card_purchase
statustext
posted
amount_centsnumber
-2499
initiated_atdate & time
2025-01-01 04:00:00
posted_atdate & time
2025-01-02 08:01:00
descriptiontext
BIRCH GYM #498
merchant_idnumber · links to merchants
968
authorization_idnumber · links to authorizations
8096
refund_idnumber · links to refunds
NULL
chargeback_idnumber · links to chargebacks
NULL
transaction_idnumber · unique id
6
account_idnumber · links to accounts
497
transaction_typetext
card_purchase
statustext
posted
amount_centsnumber
-899
initiated_atdate & time
2025-01-01 04:00:00
posted_atdate & time
2025-01-02 12:11:00
descriptiontext
VERDE STREAMING #385
merchant_idnumber · links to merchants
958
authorization_idnumber · links to authorizations
8870
refund_idnumber · links to refunds
NULL
chargeback_idnumber · links to chargebacks
NULL

first 6 of 84,798 rows · your queries use all of them

worked example

Run these steps in order to see the idea before you write your own query. The step marked “the pattern” is what the challenges ask for. Running the example does not count toward progress.

  1. See account 3’s transactions. Run this. Deposits show as positive cents and spending as negative, in the order they posted.

    step-1.sql
    SELECT transaction_id, transaction_type, status, amount_cents, posted_at
    FROM transactions
    WHERE account_id = 3
    ORDER BY posted_at, transaction_id
    LIMIT 15;
  2. Build a running total. Run this. SUM() OVER adds each posted amount to everything before it on this account, row by row—that is a running balance of movements only.the pattern

    example.sql
    SELECT
      transaction_id,
      posted_at,
      amount_cents,
      SUM(amount_cents) OVER (ORDER BY posted_at, transaction_id ROWS UNBOUNDED PRECEDING) AS cumulative_cents
    FROM transactions
    WHERE account_id = 3 AND status = 'posted';

common mistake

Without a unique tie-breaker, entries posted at the same instant can be accumulated in any order; with the default RANGE frame, tied rows also share one total.

challenge 1

For account 6’s posted entries, return transaction_id, posted_at, amount_cents and balance_cents: the opening balance plus all posted amounts up to and including this entry, ordered by posted_at then transaction_id.

what to return

Columns
transaction_idposted_atamount_centsbalance_cents in this order
Rows
any order
challenge-1.sql
 
To master this lesson, solve both challenges without hints and pass the concept check. 3 of 3 to go.
Running totals — Window functions · Runtime