The Ones Who Carry Us

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

Problem

Which products have brought in at least one hundred dollars across every sale in the transactions log, and how much revenue and how many units has each sold? The general manager reviewing product performance wants them listed by catalog product name, biggest earner first.

Every quarter, a few names hold up the whole line. Name them.

Tables

products

Columns: product_id INTEGER, product_name TEXT, category TEXT, price REAL, rating REAL, in_stock INTEGER

products: 10 of 200 rows
product_idproduct_namecategorypriceratingin_stock
1001Basic Device 1XBooks17.522.71
1050Deluxe Bundle 2XClothing25.054.41
1099Pro Unit 3XHome & Kitchen32.582.11
1148Ultra Tool 4XCollectibles40.113.81
1197Essential Set 5XToys47.641.51
1246Classic System 6XBeauty03.21
1295Smart Gadget 7XAutomotive62.74.90
1344Eco Kit 8XGarden70.232.61
1393Turbo Pack 9XMusic77.764.30
1442Premium Widget 10XElectronics85.2921

transactions

Columns: transaction_id INTEGER, user_id INTEGER, product_id INTEGER, quantity INTEGER, total_amount REAL, transaction_date TEXT

transactions: 10 of 200 rows
transaction_iduser_idproduct_idquantitytotal_amounttransaction_date
10671971001223.462026-02-02
11342941050336.932026-03-03
12013911099450.42026-04-04
12684881148563.872026-05-05
13355851197002026-06-06
14026821246290.812026-07-07
146977912953104.282026-08-08
153687613444117.752026-09-09
160397313935-452026-01-10
1670107014421144.692026-02-11

Expected output

First 5 of 89 rows
product_nametotal_revenueunits_sold
Premium Widget 100X2713.982
Eco Kit 98X2660.18
Smart Gadget 97X2633.166
Classic System 96X2606.224
Essential Set 95X2579.282

Worked solution and explanation

What this problem really is

Strip away the performance-review framing and this is a labeled aggregation with a threshold. You sum revenue per product, attach the product's name so the output is readable, and keep only the products whose total clears one hundred dollars. Anyone can write the join. The tell is where the threshold goes: a filter on the summed revenue has to run after the rows are grouped, which means HAVING, not WHERE. Put the sum in WHERE and the query errors. Filter individual sales of one hundred dollars or more instead of the product's total and you quietly report the wrong leaderboard.


Break down the requirements

Step 1: Join products to transactions

The join lines up each sale with its catalog row on the shared product_id. That is what lets the summed revenue sit next to a human-readable product_name in the output. Sales with no product recorded have nothing to name, so the inner join drops them.

Step 2: Aggregate by p.product_name

GROUP BY p.product_name collapses every sale of a product into one row, and SUM(t.total_amount) plus SUM(t.quantity) compute the revenue and units for that product. Refunds and voided sales are summed as recorded.

Step 3: Filter groups with HAVING

The one hundred dollar cut is a condition on the summed revenue, so it belongs in HAVING. WHERE cannot see the sum because it is evaluated before grouping happens.

Step 4: Sort the final output

ORDER BY total_revenue DESC puts the biggest earners on top, matching how the general manager reads the review from best to worst.


The solution

Revenue and units per product with a post-aggregation filter
SELECT p.product_name, SUM(t.total_amount) AS total_revenue, SUM(t.quantity) AS units_sold
FROM products p
JOIN transactions t ON p.product_id = t.product_id
GROUP BY p.product_name
HAVING SUM(t.total_amount) >= 100
ORDER BY total_revenue DESC

Common follow-up questions