A fraud analyst wants to spot orders that are unusually large for that particular customer, not compared with the whole platform.
From customer_orders, return order_id, customer_id, order_amount and customer_avg (that customer's average order amount, rounded to 2 decimals) for every order strictly above the customer's own average. Order by customer_id, then order_id.
Sample data
Table: customer_orders
14 row(s) · showing first 8
| order_idINT | customer_idINT | order_dateDATE | order_amountNUMERIC(10,2) |
|---|---|---|---|
| 1 | 101 | 2026-09-02 | 1200.00 |
| 2 | 101 | 2026-09-15 | 3400.00 |
| 3 | 101 | 2026-10-01 | 800.00 |
| 4 | 102 | 2026-09-05 | 5000.00 |
| 5 | 102 | 2026-09-20 | 4500.00 |
| 6 | 102 | 2026-10-10 | 9500.00 |
| 7 | 103 | 2026-09-08 | 700.00 |
| 8 | 103 | 2026-09-25 | 650.00 |
customer_orders
- order_idINT
- customer_idINT
- order_dateDATE
- order_amountNUMERIC(10,2)
- Step 1: The inner query is a correlated subquery: it references `o.customer_id` from the outer query, so it is re-evaluated for each customer.
- Step 2: The comparison is strict (`>`), so customer 105, whose two orders both equal the average, returns nothing.
- Step 3: The same subquery is used once in `SELECT` to display the average and once in `WHERE` to filter.
SELECT o.order_id,
o.customer_id,
o.order_amount,
(SELECT ROUND(AVG(i.order_amount), 2)
FROM customer_orders i
WHERE i.customer_id = o.customer_id) AS customer_avg
FROM customer_orders o
WHERE o.order_amount > (SELECT AVG(i.order_amount)
FROM customer_orders i
WHERE i.customer_id = o.customer_id)
ORDER BY o.customer_id, o.order_id;More Subqueries questions
Practising alone only goes so far — our live cohorts pair SQL depth with dashboards, agentic analytics projects and mock interviews.
Explore the program