The Heavy Lifters

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
L4
Asked in
Burtch Works

Problem

Return the product categories where orders of $1,000 or more bring in more than half of the category's total revenue, listed alphabetically. We count an order's revenue as its total_amount in transactions and take its category from the ordered product in products.

In some categories, a handful of big orders carry the rest.

Tables

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

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

Expected output

First 3 of 3 rows
category
Beauty
Sports
Toys

Worked solution and explanation

What this problem is really testing

Remove the merchandising story and this is a per-group share test. Inside each category, does the revenue from orders of $1,000 or more beat half of everything the category sold? The skill is computing a conditional numerator and the full denominator over the same group in one pass. Finding the four-figure orders is the easy part. The trap is finding them with a WHERE before the GROUP BY. That removes the smaller orders, so every group's share becomes 100 percent, and on this data you return ten categories when only three qualify.

Build it up

Step 1: Attach a category to each order

Inner-join transactions to products on product_id. Some transactions carry a NULL product_id. They have no category, and the inner join is what keeps them out of the answer.

Step 2: Group by category

GROUP BY p.category gives one row per category. Both sums must be computed over that same set of rows, and that set includes the refund and the voided sale.

Step 3: Compare big-order revenue to half the total

In HAVING, require the conditional sum to be strictly greater than 0.5 * SUM(t.total_amount). Use total_amount as stored, because it is already the order's full value; never multiply it by quantity.

The solution

Conditional numerator over the whole-category denominator
SELECT p.category
FROM transactions t
JOIN products p ON t.product_id = p.product_id
GROUP BY p.category
HAVING SUM(CASE WHEN t.total_amount >= 1000 THEN t.total_amount ELSE 0 END) > 0.5 * SUM(t.total_amount)
ORDER BY p.category
The filter-first version
SELECT p.category
FROM transactions t
JOIN products p ON t.product_id = p.product_id
WHERE t.total_amount >= 1000
GROUP BY p.category
ORDER BY p.category

Wrong: this returns every category with a single four-figure order, ten rows instead of three.

Filter first, then group
WHERE t.total_amount >= 1000 throws out the smaller orders before grouping, so each group holds only big-order revenue. Every category except 'Collectibles' has at least one such order, so ten categories come back.
Conditional sum over the whole group
The CASE inside SUM counts the small orders as zero without removing them, so SUM(t.total_amount) still sees the whole category. Only 'Beauty', 'Sports' and 'Toys' clear half.

Common follow-up questions