Present and Accounted For
An easy SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.
- Domain
- SQL
- Difficulty
- easy
- Seniority
- L3
- Asked in
- DoorDash
Problem
The merchandising team wants a per-product read on how much sales volume comes specifically from the 'Electronics' category. For every product, show the total transaction amount tied to Electronics, biggest first, and keep products that have never sold under Electronics in the list with a zero.
Every product lands on the report, even the ones Electronics never touched.
Tables
products
Columns: product_id INTEGER, product_name TEXT, category TEXT, price REAL, rating REAL, in_stock INTEGER
| product_id | product_name | category | price | rating | in_stock |
|---|---|---|---|---|---|
| 1001 | Basic Device 1X | Books | 17.52 | 2.7 | 1 |
| 1050 | Deluxe Bundle 2X | Clothing | 25.05 | 4.4 | 1 |
| 1099 | Pro Unit 3X | Home & Kitchen | 32.58 | 2.1 | 1 |
| 1148 | Ultra Tool 4X | Collectibles | 40.11 | 3.8 | 1 |
| 1197 | Essential Set 5X | Toys | 47.64 | 1.5 | 1 |
| 1246 | Classic System 6X | Beauty | 0 | 3.2 | 1 |
| 1295 | Smart Gadget 7X | Automotive | 62.7 | 4.9 | 0 |
| 1344 | Eco Kit 8X | Garden | 70.23 | 2.6 | 1 |
| 1393 | Turbo Pack 9X | Music | 77.76 | 4.3 | 0 |
| 1442 | Premium Widget 10X | Electronics | 85.29 | 2 | 1 |
transactions
Columns: transaction_id INTEGER, product_id INTEGER, total_amount REAL, user_id INTEGER, quantity INTEGER, 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
| product_name | electronics_total |
|---|---|
| Premium Widget 100X | 2713.98 |
| Premium Widget 90X | 2444.58 |
| Premium Widget 80X | 2175.18 |
| Premium Widget 70X | 1905.78 |
| Premium Widget 60X | 1636.38 |
Worked solution and explanation
What this problem really is
This is a conditional sum wearing a join costume. The real question: can you total each product's Electronics volume while still listing the products that sold zero Electronics? Anyone can sum the amounts. The trap is where the category filter lives. Push 'category = Electronics' into a WHERE clause and your LEFT JOIN silently collapses to an INNER JOIN, and every product that never sold an Electronics item vanishes from the report the business explicitly asked to see in full.
Break down the requirements
Step 1: Start from all products
LEFT JOIN products to transactions on product_id, driving from products so every product survives, even the ones with no transactions at all.
Step 2: Filter inside the aggregate, not in WHERE
Keep the category test inside the aggregate: SUM(CASE WHEN p.category = 'Electronics' THEN t.total_amount END). Non-Electronics rows contribute nothing to the sum, but the product row itself is never dropped.
Step 3: Zero-fill the empty case
A product with no Electronics volume produces a NULL sum. Wrap it in COALESCE(..., 0) so the report reads 0 for those products instead of a blank.
The solution
SELECT p.product_name,
COALESCE(SUM(CASE WHEN p.category = 'Electronics' THEN t.total_amount END), 0) AS electronics_total
FROM products p
LEFT JOIN transactions t ON p.product_id = t.product_id
GROUP BY p.product_id, p.product_name
ORDER BY electronics_total DESC, p.product_name- Filter in the aggregate (correct)
- SUM(CASE WHEN p.category = 'Electronics' THEN
t.total_amountEND) leaves every product row intact and simply contributes 0 for the non-Electronics ones. All products stay in the output. - Filter in WHERE (drops products)
- WHERE p.category = 'Electronics' evaluates after the LEFT JOIN and discards every row where the match is absent, turning the outer join into an inner one. Products with no Electronics volume disappear entirely.
Common follow-up questions
- Walk me through what changes if you move the category predicate into the WHERE clause. (Tests understanding of WHERE vs ON vs conditional-aggregate semantics in a LEFT JOIN.)
- How would you extend this to show each category's volume as its own column in one row per product? (Tests conditional aggregation / pivot patterns.)
- What breaks if `product_id` is not unique in the products table? (Tests awareness of how duplicate keys in the left table inflate sums.)