What if your database could think like a smart assistant, checking only what matters for each question you ask?
Why Correlated subqueries execution model in PostgreSQL? - Purpose & Use Cases
Imagine you have a big stack of papers with customer orders and you want to find the latest order date for each customer by flipping through the entire stack again and again for every single customer.
Doing this by hand is slow and tiring. You might lose track, make mistakes, or waste a lot of time repeating the same search over and over for each customer.
Correlated subqueries let the database automatically look up related data for each row efficiently, like having a smart assistant who checks only the relevant papers for each customer without flipping the whole stack every time.
SELECT customer_id FROM orders;
-- Then for each customer, run:
SELECT MAX(order_date) FROM orders WHERE customer_id = ?;SELECT customer_id, (SELECT MAX(order_date) FROM orders o2 WHERE o2.customer_id = o1.customer_id) AS latest_order FROM orders o1;
This lets you write clear queries that automatically fetch related data row-by-row, making complex data questions easy and fast to answer.
A store manager wants to see each customer's most recent purchase date alongside their details without manually searching through all sales records repeatedly.
Manual searching for related data is slow and error-prone.
Correlated subqueries automate row-by-row related data lookup.
This makes queries simpler and more efficient for complex data tasks.
Practice
correlated subquery in PostgreSQL?Solution
Step 1: Understand the definition of correlated subquery
A correlated subquery references columns from the outer query and runs once per outer row.Step 2: Compare options with this behavior
Only It runs the inner query once for each row of the outer query. correctly states that the inner query runs once per outer row.Final Answer:
It runs the inner query once for each row of the outer query. -> Option AQuick Check:
Correlated subquery = runs per outer row [OK]
- Thinking inner query runs once for all rows
- Assuming no reference to outer query columns
- Confusing correlated with uncorrelated subqueries
Solution
Step 1: Identify the correlated subquery condition
SELECT e.name FROM employees e WHERE e.salary > (SELECT AVG(salary) FROM employees e2 WHERE e2.department = e.department); references the outer query aliase.departmentinside the inner query, making it correlated.Step 2: Check other options for correlation
Options B, C, and D do not reference outer query columns inside the subquery, so they are not correlated.Final Answer:
SELECT e.name FROM employees e WHERE e.salary > (SELECT AVG(salary) FROM employees e2 WHERE e2.department = e.department); -> Option AQuick Check:
Correlation requires outer reference inside subquery [OK]
- Missing outer query reference in subquery
- Using same alias for outer and inner queries
- Confusing filtering with correlation
departments(id, name) and employees(id, name, department_id, salary), what will this query return?SELECT d.name, (SELECT AVG(e.salary) FROM employees e WHERE e.department_id = d.id) AS avg_salary FROM departments d;
Solution
Step 1: Identify the correlation in the subquery
The subquery usese.department_id = d.id, linking inner query to outer query row.Step 2: Understand the output
For each department, the subquery calculates average salary of employees in that department.Final Answer:
Each department name with the average salary of its employees. -> Option BQuick Check:
Correlated subquery returns per outer row result [OK]
- Assuming subquery returns overall average salary
- Thinking subquery is uncorrelated and runs once
- Confusing department and employee columns
SELECT e1.name FROM employees e1 WHERE e1.salary > (SELECT AVG(salary) FROM employees e1 WHERE e1.department_id = e1.department_id);
Solution
Step 1: Analyze alias usage in inner and outer queries
Both inner and outer queries use aliase1, causing the inner query to reference itself only.Step 2: Understand impact on correlation
Because of alias shadowing, the subquery conditione1.department_id = e1.department_idis always true and not correlated to outer row.Final Answer:
The inner query alias shadows the outer query alias causing incorrect correlation. -> Option DQuick Check:
Use different aliases to avoid shadowing [OK]
- Using same alias for inner and outer queries
- Assuming WHERE clause is missing
- Confusing alias shadowing with syntax error
Solution
Step 1: Understand the requirement
We need to compare the max salary per department with the average salary per department.Step 2: Analyze each option's logic
SELECT d.name FROM departments d WHERE (SELECT MAX(e.salary) FROM employees e WHERE e.department_id = d.id) > (SELECT AVG(e2.salary) FROM employees e2 WHERE e2.department_id = d.id); uses two correlated subqueries referencingd.idto get max and average salary per department, correctly implementing the condition.Step 3: Identify errors in other options
SELECT d.name FROM departments d WHERE MAX(e.salary) > AVG(e.salary) FROM employees e WHERE e.department_id = d.id; has invalid syntax mixing aggregation and WHERE clause. SELECT d.name FROM departments d JOIN employees e ON e.department_id = d.id WHERE e.salary > (SELECT AVG(salary) FROM employees); compares employee salary to overall average, not per department. SELECT d.name FROM departments d WHERE EXISTS (SELECT 1 FROM employees e WHERE e.department_id = d.id AND e.salary > (SELECT AVG(salary) FROM employees)); compares employee salary to overall average, not per department.Final Answer:
SELECT d.name FROM departments d WHERE (SELECT MAX(e.salary) FROM employees e WHERE e.department_id = d.id) > (SELECT AVG(e2.salary) FROM employees e2 WHERE e2.department_id = d.id); -> Option CQuick Check:
Use correlated subqueries for per-department aggregates [OK]
- Mixing aggregation without GROUP BY
- Comparing to overall average instead of per department
- Incorrect syntax for aggregation in WHERE clause
Ready to prove it?
Pass the test and this pattern moves unknown
