Above Average Product Prices

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
Publicis Sapient

Problem

The finance team defines a product's base price as the lowest transaction amount ever recorded for it. They want to flag products whose base price runs above the average base price across all products. Return the product ID and its base price.

Some products cost more than they should.

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

Expected output

First 5 of 46 rows
product_idbase_price
3402683.49
3451696.96
3500710.43
3549723.9
3598737.37

Worked solution and explanation

Why this problem exists in real interviews

A derived-threshold filter: compute a per-group aggregate (MIN total_amount per product_id), then keep groups whose aggregate beats the average of that same aggregate across all products. The interviewer is watching whether you name 'average of what' before you write.


Break down the requirements

Step 1: Define base price

Per product_id, base_price = MIN(total_amount) over the transactions table. One row per product after the GROUP BY.

Step 2: Define the threshold

Average of base prices across all products, not the average of every transaction. The scalar subquery is MIN per product first, then AVG over those mins.

Step 3: Filter with HAVING, not WHERE

MIN(total_amount) is an aggregate; the comparison to the scalar subquery belongs in HAVING. WHERE evaluates before aggregation and can't see MIN.

Step 4: Return product_id and base_price

SELECT product_id, MIN(total_amount) AS base_price. No ORDER BY required by the prompt; add one if asked.


The solution

MIN PER PRODUCT VS AVG OF MINS
SELECT
  product_id,
  MIN(total_amount) AS base_price
FROM transactions
GROUP BY product_id
HAVING MIN(total_amount) > (
  SELECT AVG(min_price)
  FROM (
    SELECT MIN(total_amount) AS min_price
    FROM transactions
    GROUP BY product_id
  )
)

COMMON FOLLOW-UP QUESTIONS

Common follow-up questions