Deep Pockets
A medium SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.
- Domain
- SQL
- Difficulty
- medium
- Seniority
- L3
- Asked in
- Amazon
Problem
We're closing the books for March 2026 and need a spend breakdown by customer. Total each customer's transactions for the month.
One month, every customer, every dollar accounted for.
Tables
transactions
Columns: transaction_id INTEGER, user_id INTEGER, product_id INTEGER, quantity INTEGER, total_amount REAL, transaction_date TEXT
| transaction_id | user_id | product_id | quantity | total_amount | transaction_date |
|---|---|---|---|---|---|
| 1067 | 197 | 1001 | 2 | 23.46 | 2026-02-02 |
| 1134 | 294 | 1050 | 3 | 36.93 | 2026-03-03 |
| 1201 | 391 | 1099 | 4 | 50.4 | 2026-04-04 |
| 1268 | 488 | 1148 | 5 | 63.87 | 2026-05-05 |
| 1335 | 585 | 1197 | 0 | 0 | 2026-06-06 |
| 1402 | 682 | 1246 | 2 | 90.81 | 2026-07-07 |
| 1469 | 779 | 1295 | 3 | 104.28 | 2026-08-08 |
| 1536 | 876 | 1344 | 4 | 117.75 | 2026-09-09 |
| 1603 | 973 | 1393 | 5 | -45 | 2026-01-10 |
| 1670 | 1070 | 1442 | 1 | 144.69 | 2026-02-11 |
Expected output
| user_id | total_revenue |
|---|---|
| 100 | 1434.33 |
| 294 | 1929.24 |
| 585 | 1164.9299999999998 |
| 876 | 1649.85 |
| 1167 | 922.4699999999999 |
Worked solution and explanation
What this problem is really testing
This is a plain per-customer sum wearing a finance costume. The whole game is the date boundary. Anyone can write GROUP BY user_id with SUM(total_amount); what separates people is expressing 'March' as a half-open range instead of reaching for BETWEEN or LIKE, and NOT bolting on a redundant filter for 'users with at least one transaction' when the grouping already guarantees that. Botch the boundary and you either swallow April 1 or drop the last day of March, and finance reconciles against a total that is quietly wrong.
Break down the requirements
Step 1: Filter to March of the target year
Use WHERE transaction_date >= '2026-03-01' AND transaction_date < '2026-04-01'. The half-open range captures every March date, including the 31st, and cleanly excludes April even if a time component sneaks in later.
Step 2: Aggregate per customer
GROUP BY user_id with SUM(total_amount) gives each customer's March spend. Because you are grouping the transactions themselves, only customers who actually transacted in March appear. The 'at least one transaction' requirement is satisfied for free, so an extra HAVING or existence check is wasted work.
Step 3: Sort highest to lowest
ORDER BY total_revenue DESC puts the biggest spenders at the top, which is what finance reads first.
The solution
SELECT user_id, SUM(total_amount) AS total_revenue
FROM transactions
WHERE transaction_date >= '2026-03-01'
AND transaction_date < '2026-04-01'
GROUP BY user_idCommon follow-up questions
- How would you modify this to show revenue by month for the entire year? (Tests adding date truncation to the GROUP BY for a time-series pivot.)
- What if you needed to include customers with zero March transactions? (Requires a LEFT JOIN from a customers table so zero-spend customers survive.)
- What if `transaction_date` included timestamps with time components? (Confirms the half-open interval still behaves correctly once time components exist.)