Script Valley
SQL for Developers (Not DBAs)
Subqueries and CTEsLesson 5.2

Correlated subqueries - what they are and when they are slow

correlated subquery, outer query reference, EXISTS, NOT EXISTS, performance implications, when to use vs rewrite

Correlated Subqueries Reference the Outer Query

Correlated subquery diagram

A regular subquery runs once. A correlated subquery references a column from the outer query, so it runs once per outer row. This makes them powerful but potentially slow on large tables.

-- For each order, find orders with higher amount by the same customer
SELECT o1.id, o1.amount
FROM orders o1
WHERE o1.amount > (
  SELECT AVG(o2.amount)
  FROM orders o2
  WHERE o2.customer_id = o1.customer_id  -- references outer query
);

EXISTS Is the Best Use of Correlated Subqueries

EXISTS stops as soon as it finds one matching row - it doesn't build the full result set. Use it to check for the presence of related rows:

-- Customers who have at least one completed order
SELECT c.id, c.name
FROM customers c
WHERE EXISTS (
  SELECT 1 FROM orders o
  WHERE o.customer_id = c.id
  AND o.status = 'completed'
);

The SELECT 1 inside EXISTS is conventional - EXISTS only cares whether rows exist, not what columns are returned. NOT EXISTS is also safe with NULLs, unlike NOT IN.

Up next

CTEs with WITH - making complex queries readable

Sign in to track progress

Correlated subqueries - what they are and when they are slow · Subqueries and CTEs· SQL for Developers (Not DBAs) · Script Valley — Script Valley