Why subqueries are needed in PostgreSQL - Performance Analysis
We want to understand how the time to run a query changes when it uses subqueries.
Specifically, we ask: How does adding a subquery affect the work the database does?
Analyze the time complexity of this SQL query using a subquery.
SELECT employee_id, name
FROM employees
WHERE department_id IN (
SELECT department_id
FROM departments
WHERE location = 'New York'
);
This query finds employees who work in departments located in New York by using a subquery to get those department IDs first.
Look for repeated steps in the query execution.
- Primary operation: The subquery runs first to find matching department IDs.
- How many times: The subquery runs once, then the main query checks each employee against the subquery result.
As the number of departments and employees grows, the work changes like this:
| Input Size (n) | Approx. Operations |
|---|---|
| 10 departments, 100 employees | Subquery: 10 checks, Main query: 100 checks |
| 100 departments, 1,000 employees | Subquery: 100 checks, Main query: 1,000 checks |
| 1,000 departments, 10,000 employees | Subquery: 1,000 checks, Main query: 10,000 checks |
Pattern observation: The subquery work grows with departments, and the main query work grows with employees.
Time Complexity: O(m + n)
This means the total work grows roughly by adding the size of the subquery input (departments) and the main query input (employees).
[X] Wrong: "The subquery runs once for each employee, so time grows like m x n."
[OK] Correct: In this case, the subquery runs only once, and its results are used to filter employees, so the work adds up, not multiplies.
Understanding how subqueries affect query time helps you write efficient database queries and explain your choices clearly in real projects or interviews.
"What if the subquery was correlated to the main query? How would the time complexity change?"
Practice
SELECT * FROM employees WHERE department_id IN (SELECT id FROM departments WHERE location = 'NY');Solution
Step 1: Understand the role of the subquery
The subquery(SELECT id FROM departments WHERE location = 'NY')finds department IDs located in NY.Step 2: See how the main query uses the subquery
The main query selects employees whosedepartment_idmatches any ID from the subquery result.Final Answer:
To ask a question inside another query and filter results based on it -> Option CQuick Check:
Subqueries filter data using inner query results [OK]
- Thinking subqueries speed up queries automatically
- Confusing subqueries with table creation
- Using subqueries to change data types
Solution
Step 1: Identify correct subquery syntax
Subqueries must be enclosed in parentheses and used with comparison operators like = or IN.Step 2: Check each option
SELECT * FROM table WHERE column = (SELECT MAX(column) FROM table);correctly uses parentheses and = with a subquery. The other options have syntax errors like using == instead of =, omitting parentheses entirely, or missing them after IN.Final Answer:
SELECT * FROM table WHERE column = (SELECT MAX(column) FROM table); -> Option BQuick Check:
Subqueries need parentheses and proper operators [OK]
- Using double equals (==) instead of single equals (=)
- Omitting parentheses around subqueries
- Using IN without parentheses
SELECT name FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
Solution
Step 1: Understand the subquery
The subquery(SELECT AVG(salary) FROM employees)calculates the average salary of all employees.Step 2: Apply the condition in the main query
The main query selects employee names where their salary is greater than this average.Final Answer:
Names of employees earning more than the average salary -> Option DQuick Check:
Subquery returns average; main query filters salaries above it [OK]
- Thinking it returns employees below average
- Assuming syntax error due to subquery
- Confusing AVG with SUM
SELECT name FROM employees WHERE department_id = SELECT id FROM departments WHERE name = 'Sales';
Solution
Step 1: Check subquery syntax
The subquery must be enclosed in parentheses to be valid in the WHERE clause.Step 2: Identify the missing parentheses
The query misses parentheses aroundSELECT id FROM departments WHERE name = 'Sales', causing syntax error.Final Answer:
Missing parentheses around the subquery -> Option AQuick Check:
Subqueries need parentheses to be valid [OK]
- Forgetting parentheses around subqueries
- Assuming wrong operator causes error
- Thinking table name is incorrect
Solution
Step 1: Understand the requirement
We need to compare each employee's salary to the average salary of their own department.Step 2: Analyze each option
SELECT name, salary, department_id FROM employees WHERE salary > (SELECT AVG(salary) FROM employees WHERE department_id = employees.department_id); uses a correlated subquery that calculates average salary per employee's department. SELECT name, salary FROM employees WHERE salary > (SELECT AVG(salary) FROM employees); compares to overall average, ignoring departments. SELECT name FROM employees WHERE salary > ALL (SELECT salary FROM employees); compares salary to all salaries, not averages. SELECT name FROM employees WHERE salary > ANY (SELECT AVG(salary) FROM employees GROUP BY department_id); compares to a list of averages but uses ANY incorrectly.Final Answer:
SELECT name, salary, department_id FROM employees WHERE salary > (SELECT AVG(salary) FROM employees WHERE department_id = employees.department_id); -> Option AQuick Check:
Correlated subquery compares salary to department average [OK]
- Comparing to overall average instead of department average
- Using ALL or ANY incorrectly with averages
- Not correlating subquery with outer query
Ready to prove it?
Pass the test and this pattern moves unknown
