Going Once

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
TikTok

Problem

The product team is building a sales leaderboard for in-stock items. For each product currently in stock, show how many transactions reference it, the highest transaction amount, and which user placed the top transaction; products with no transactions should still appear, showing a count of zero and no top user. Walk the catalog in product-ID order, from the lowest number up.

The hammer falls. Who bid the most?

Tables

products

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

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, product_id INTEGER, total_amount REAL, user_id INTEGER, quantity INTEGER, 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 158 rows
product_idproduct_namebid_counthighest_bidwinner
1001Basic Device 1X3225.51197
1050Deluxe Bundle 2X3238.98294
1099Pro Unit 3X250.4391
1491Basic Device 11X0NULLNULL
1736Classic System 16X1225.51197

Worked solution and explanation

What this problem is really about

This is 'fetch the row that owns the aggregate' wearing an auction costume. Anyone can hand you MAX(total_amount) per product with a GROUP BY. The skill being probed is returning WHO placed that top transaction in the same pass: MAX gives you the number, not the user_id attached to it. A correlated subquery or self-join gets the winner, but it re-scans the entire transactions table once per product. The clean move is ROW_NUMBER() in a CTE to tag each product's top bid once, then an outer join back to it. And there is a trap in the empties: filter the products with an inner join and every in-stock listing that never sold silently disappears; the count has to survive as 0 with a NULL winner.


Break down the requirements

Step 1: Rank each product's bids

In ranked_bids, rank transactions within each product_id by total_amount descending, with transaction_id as the tie-breaker for determinism, using ROW_NUMBER().

Step 2: Outer-join so empty products survive

LEFT JOIN the in-stock products to transactions so products with no transactions are retained, and to ranked_bids restricted to rn = 1 to surface the top-transaction user.

Step 3: Aggregate to one row per product

Aggregate per product: COUNT(t.transaction_id) gives 0 for transaction-less products, MAX(t.total_amount) gives the highest bid, and the rn = 1 user_id is the winner (NULL when no transactions).

Step 4: Order by product id

Order by product_id, lowest first. The key is unique per row, so the order is total.


The solution

Row-number for auction lot summary
WITH ranked_bids AS (
    SELECT
        product_id,
        user_id,
        ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY total_amount DESC, transaction_id) AS rn
    FROM transactions
)
SELECT
    p.product_id,
    p.product_name,
    COUNT(t.transaction_id) AS bid_count,
    MAX(t.total_amount) AS highest_bid,
    rb.user_id AS winner
FROM products p
LEFT JOIN transactions t ON p.product_id = t.product_id
LEFT JOIN ranked_bids rb ON p.product_id = rb.product_id AND rb.rn = 1
WHERE p.in_stock = 1
GROUP BY p.product_id, p.product_name, rb.user_id
ORDER BY p.product_id;

Common follow-up questions