BBampaa

Lessons › SQL › Deep Dive: Advanced Joins & Subqueries

SQL lesson

Correlated subqueries

A correlated subquery is a mini-query nested inside a larger one that reruns for every single row, using a value from that row to shape its own result.

Try this lesson free →
About 5–10 minutes · no sign-up needed

Example

Comparing Each Retail Order with a Correlated Subquery

SELECT order_id, customer_id, revenue
FROM orders o
WHERE revenue > (
  SELECT AVG(revenue)
  FROM orders i
  WHERE i.customer_id = o.customer_id
)

Result:

order_idcustomer_idrevenue
O2001C101120.5
O2003C102200.75

Step by step

  1. Run the query without AVG so you can see what the unfiltered values look like.
    SELECT order_id, customer_id, revenue
    FROM orders o
    WHERE revenue > (
      SELECT revenue
      FROM orders i
      WHERE i.customer_id = o.customer_id
    );
  2. AVG returns the mean of the values in a column.
    SELECT order_id, customer_id, revenue
    FROM orders o
    WHERE revenue > (
      SELECT AVG(revenue)
      FROM orders i
      WHERE i.customer_id = o.customer_id
    );
  3. AS gives the AVG result a friendly column name so the output reads cleanly.
    SELECT order_id, customer_id, revenue
    FROM orders o
    WHERE revenue > (
      SELECT AVG(revenue) AS avg_result
      FROM orders i
      WHERE i.customer_id = o.customer_id
    );

Practice

Try each one in your head first, then open the answer.

1. Using orders as t1, write a correlated subquery that finds rows where revenue is greater than the average revenue for that row's category.
SELECT * FROM orders t1 WHERE revenue > (SELECT AVG(revenue) FROM orders t2 WHERE t2.category = t1.category)
2. Using customers as t1, write a correlated subquery that finds rows where email is greater than the average email for that row's phone.
SELECT * FROM customers t1 WHERE email > (SELECT AVG(email) FROM customers t2 WHERE t2.phone = t1.phone)
3. Using products as t1, write a correlated subquery that finds rows where price is greater than the average price for that row's brand.
SELECT * FROM products t1 WHERE price > (SELECT AVG(price) FROM products t2 WHERE t2.brand = t1.brand)
4. Using store_sales as t1, write a correlated subquery that finds rows where revenue is greater than the average revenue for that row's store_id.
SELECT * FROM store_sales t1 WHERE revenue > (SELECT AVG(revenue) FROM store_sales t2 WHERE t2.store_id = t1.store_id)
5. Using employees as t1, write a correlated subquery that finds rows where salary is greater than the average salary for that row's full_name.
SELECT * FROM employees t1 WHERE salary > (SELECT AVG(salary) FROM employees t2 WHERE t2.full_name = t1.full_name)

Learn it by doing. This lesson is a short hands-on level on Bampaa: see it work, then build and write it yourself, with instant feedback.

Try this lesson free →
About 5–10 minutes · no sign-up needed