SQL-Engineering-Handbook

04 · Banking — Window Functions in Transaction & Risk Analytics

Running balance with a per-account fraud baseline

Introduction

Banking data is sequential by nature: every account has an ordered history of transactions, and nearly every question a risk or operations team asks is really a question about how a transaction relates to the ones around it — is this withdrawal unusually large compared to this account’s own history? Has the balance dropped sharply? Is there a suspicious gap or spike in transaction frequency? This chapter applies the running-total and gap-analysis patterns from earlier chapters to the highest-stakes domain in this module: financial risk.


Business Background

A simplified banking schema centers on accounts and their transaction ledger:

Risk, fraud, and operations teams consume this data primarily through running balances, outlier detection relative to an account’s own history, and gap/frequency analysis.


Typical KPIs


Typical Dashboards


Business Problems

  1. “Reconstruct the running balance for every account, transaction by transaction.”
  2. “Show me the largest transactions bank-wide, for manual review.”
  3. “Flag any transaction that’s unusually large compared to that specific account’s own transaction history - a first-pass fraud signal.”
  4. “What’s the time gap between consecutive transactions on an account? Flag accounts with unusually long dormancy followed by sudden activity.”
  5. “Rank customers by total transaction volume, for a relationship-banking outreach list.”
  6. “Compare each account’s current balance to its balance at the start of the month.”

Why Window Functions Are Needed

A running balance is, definitionally, a running total - SUM(amount) OVER (PARTITION BY account_id ORDER BY transaction_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) - reusing the exact pattern from Sales Analytics, now applied per account rather than per salesperson. Fraud-style outlier detection compares a transaction to the mean and standard deviation of that same account’s own history - the identical pattern used for the HR pay-equity screen in Chapter 01, applied here to transaction amounts instead of salaries. This consistency is intentional: window functions solve a small number of structural problems, and once you recognize the shape of the problem, the domain becomes a matter of relabeling columns.


Functions Used in This Chapter

Function Business Explanation
SUM() OVER (PARTITION BY account_id ORDER BY transaction_date ...) Running account balance reconstruction.
RANK() Largest transactions bank-wide; customer ranking by transaction volume.
AVG() / STDDEV() OVER (PARTITION BY account_id) Per-account baseline for outlier / fraud-signal detection.
LAG() Time and amount gap between consecutive transactions on an account.
FIRST_VALUE() Balance at the start of a period, for period-over-period balance comparison.

SQL Concepts Reinforced


Performance Notes


Common Mistakes


Interview Questions

  1. “How would you reconstruct a running account balance from a transaction ledger?” — Expect SUM(amount) OVER (PARTITION BY account_id ORDER BY transaction_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), with attention to signed amounts and deterministic ordering.
  2. “How would you flag potentially fraudulent transactions using only SQL?” — Expect a discussion of per-account mean/standard-deviation baselines (AVG()/STDDEV() OVER (PARTITION BY account_id)) and a threshold-based flag, with the caveat that this is a first-pass heuristic, not a full fraud model.
  3. “Why is ordering important when calculating a running balance, and what happens if two transactions share the same timestamp?” — Expect recognition that ties in the ORDER BY column make the running balance non-deterministic unless a tiebreaker (e.g., transaction_id) is added.
  4. “How would you find the account with the largest balance drop within a single day?” — Expect LAG() on the running balance itself (a window function applied to the output of another window function, typically via a CTE), then a computed delta.
  5. “What’s the difference between windowing a statistic per account versus computing it once for the whole table, in a risk-detection context?” — Expect an explanation of why global baselines under- or over-flag depending on an account’s typical transaction size.

Summary

Banking analytics is where the running-total pattern (Sales Analytics) and the peer/self-comparison pattern (HR Analytics) converge on the highest-stakes use case in this module: financial risk. Every pattern in this chapter - running balances, per-account outlier baselines, and transaction gap analysis - reuses tools you have already built fluency with, applied to a domain where correctness and determinism carry real financial consequences.


Further Practice


Next: 04_BANKING.sql — the fully engineered SQL chapter for this domain.


Previous: 03_ECOMMERCE.md · Module: README · Next chapter: 05_FINANCE.md