SQL Practice Problem

Category with the highest sales

Medium Subqueries

Schema and sample data

Products
product_idcategoryprice
1Electronics500.00
2Electronics200.00
3Books20.00
4Books15.00
5Clothing40.00
6Clothing60.00
OrderItems
order_item_idproduct_idquantity
113
222
3310
445
558
664
711
Show setup SQL (copy to run)
CREATE TABLE Products (
    product_id INT PRIMARY KEY,
    category   VARCHAR(30) NOT NULL,
    price      DECIMAL(10,2) NOT NULL
);

CREATE TABLE OrderItems (
    order_item_id INT PRIMARY KEY,
    product_id    INT NOT NULL,
    quantity      INT NOT NULL
);

INSERT INTO Products (product_id, category, price) VALUES
(1, 'Electronics', 500.00),
(2, 'Electronics', 200.00),
(3, 'Books',       20.00),
(4, 'Books',       15.00),
(5, 'Clothing',    40.00),
(6, 'Clothing',    60.00);

INSERT INTO OrderItems (order_item_id, product_id, quantity) VALUES
(1, 1, 3),
(2, 2, 2),
(3, 3, 10),
(4, 4, 5),
(5, 5, 8),
(6, 6, 4),
(7, 1, 1);
Your task

You have a Products table and an OrderItems table. Total revenue for a category is SUM(price * quantity) across every order line for products in that category. Return the single category with the highest total revenue, along with that revenue. If there were a tie for the top, returning all tied categories is acceptable.

Expected result

Your query should return
categoryrevenue
Electronics2400.00
Show hint

Join OrderItems to Products so each order line knows its category and price, then GROUP BY category and total up SUM(price * quantity). To pick just the winner, sort by that total descending and keep the top row.

Try to write the query yourself before you open this.

Show solution and explanation
SELECT TOP 1 WITH TIES
    p.category,
    SUM(p.price * oi.quantity) AS revenue
FROM Products p
JOIN OrderItems oi ON oi.product_id = p.product_id
GROUP BY p.category
ORDER BY revenue DESC;

Each order line lives in OrderItems but the price and category live in Products, so the first step is a join on product_id. After the join, every line carries its price and category, and price * quantity gives the revenue for that line. Grouping by category and taking SUM of that product rolls the lines up into one total per category.

Working the sample data: Electronics = 500*3 + 200*2 + 500*1 = 1500 + 400 + 500 = 2400; Books = 20*10 + 15*5 = 200 + 75 = 275; Clothing = 40*8 + 60*4 = 320 + 240 = 560. Electronics wins at 2400.00. ORDER BY revenue DESC sorts the totals highest first, and TOP 1 keeps only the leader. Using TOP 1 WITH TIES is a small safety net: if two categories were tied for the highest revenue it returns both instead of arbitrarily dropping one.

A common mistake is to sum price without multiplying by quantity, which counts a 10-unit line the same as a 1-unit line. Another is joining in the wrong direction and losing categories that have orders. If you prefer a subquery, you can compute the per-category totals first and then keep only the ones equal to the maximum: ... GROUP BY category HAVING SUM(price * quantity) = (SELECT MAX(t.rev) FROM (SELECT SUM(price * quantity) AS rev FROM Products JOIN OrderItems ...) t). That HAVING = MAX form naturally returns every tied category and mirrors what WITH TIES does here.

Keep practising

Work through more Medium exercises, or test yourself with the SQL interview questions.