SQL Quest › SQL Interview Questions › Subqueries & CTEs
Spend and Disputes Per Cardholder — Without the Fan-Out
This is the mistake a card screen is built to catch. An account has many transactions AND many chargebacks. Join all three tables in one chain — accounts JOIN transactions JOIN chargebacks ON account_id — and every transaction row is repeated once per chargeback the account has. Account 156 has 11 transactions and 5 chargebacks; the naive query returns 55 rows for it and reports its spend at five times the true figure. Nothing errors. The number is just wrong.
The fix is to never join two one-to-many children of the same parent at row level: aggregate each branch to one row per account first, in its own CTE, then join the summaries.
Return the 20 cardholders with the most disputes: account_id, email, txn_count, total_spend (rounded to 2 decimals) and chargeback_count. Every account has transactions but most have no chargebacks, so that branch is a LEFT JOIN and its NULL becomes 0 — COALESCE(d.chargeback_count, 0). Order by chargeback_count descending, then total_spend descending, then account_id ascending.
Solve it in the browser editor →
Runs on SQLite in your browser, graded against the expected result, no signup. A wrong answer gets a diagnosis, not just "incorrect".
Schema
accounts
| account_id | signup_at | country | device_fingerprint | ip_block | status | |
|---|---|---|---|---|---|---|
| 1 | user1@example.com | 2026-02-24T00:00:00.000Z | TR | dev_13c0cdad | 41.116.196.153 | active |
| 2 | user2@inbox.dev | 2025-05-13T00:00:00.000Z | JP | dev_26576d49 | 38.98.201.102 | active |
| 3 | user3@inbox.dev | 2026-04-25T00:00:00.000Z | JP | dev_42f1a115 | 190.77.45.244 | flagged |
transactions
| txn_id | account_id | amount | txn_at | merchant_id | lat | lng | status |
|---|---|---|---|---|---|---|---|
| 1 | 149 | 151.84 | 2026-03-04T12:39:39.078Z | 24 | 40.342 | -74.4092 | completed |
| 2 | 21 | 10.72 | 2026-03-04T13:04:50.641Z | 7 | 52.9366 | 13.3229 | completed |
| 3 | 35 | 158.78 | 2026-03-04T13:27:15.528Z | 25 | 52.7397 | 13.3134 | completed |
chargebacks
| chargeback_id | txn_id | account_id | merchant_id | reason_code | opened_at | resolved_at | status | related_chargeback_id |
|---|---|---|---|---|---|---|---|---|
| 1 | 8 | 160 | 10 | service_not_received | 2026-03-06T16:52:17.429Z | 2026-04-06T16:52:17.429Z | split | NULL |
| 2 | 164 | 42 | 16 | fraud_card_not_present | 2026-03-16T23:50:46.792Z | 2026-04-22T23:50:46.792Z | open | 1 |
| 3 | 172 | 48 | 20 | fraud_card_present | 2026-03-12T05:22:57.195Z | 2026-04-14T05:22:57.195Z | cardholder_won | 2 |
Expected output: 156 user156@example.com 11 7190.81 5; 17 user17@mail.test 24 9170.65 4; ...
Hint
SELECT, CTE, JOIN, and open the hint there if you stall.Concepts
SELECT CTE JOIN LEFT JOIN GROUP BY SUM Multi-CTE
Practise the topic: SQL practice questions · CTE practice · JOIN practice · GROUP BY exercises
In these company practice sets
A SQL Quest challenge matched to patterns reported for these companies — not a question any of them has published.
Related questions
Where would this cost you points in an interview?
Ten questions, no signup: a Skillmap across nine SQL skills and the one to fix first.
Take the readiness test