Correlated subqueries let you compare each row of one table with rows in another table. They help answer questions where you need to check related data row by row.
Correlated subqueries execution model in PostgreSQL
SELECT column1, column2 FROM table1 WHERE columnX operator ( SELECT columnY FROM table2 WHERE table2.columnZ = table1.columnA );
The subquery refers to a column from the outer query, making it 'correlated'.
The subquery runs once for each row of the outer query, which can affect performance.
SELECT e.name FROM employees e WHERE e.salary > ( SELECT AVG(salary) FROM employees WHERE department = e.department );
SELECT c.customer_id FROM customers c WHERE EXISTS ( SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id AND o.amount > 100 );
This query lists employees who earn more than the average salary in their department. The subquery calculates the average salary for the department of each employee row.
CREATE TABLE employees ( id SERIAL PRIMARY KEY, name TEXT, department TEXT, salary INT ); INSERT INTO employees (name, department, salary) VALUES ('Alice', 'Sales', 5000), ('Bob', 'Sales', 4000), ('Carol', 'HR', 4500), ('Dave', 'HR', 5500); SELECT name, salary, department FROM employees e WHERE salary > ( SELECT AVG(salary) FROM employees WHERE department = e.department );
Correlated subqueries can be slower because the inner query runs for each outer row.
Sometimes you can rewrite correlated subqueries using JOINs for better performance.
Understanding how the subquery depends on the outer query helps avoid mistakes.
Correlated subqueries run the inner query once per outer row, using values from that row.
They are useful for row-by-row comparisons or checks involving related tables.
Be mindful of performance and consider alternatives like JOINs when possible.