Subqueries are one of the most powerful features in SQL, enabling complex queries and advanced data manipulation.
A subquery is a SQL query nested inside another query. It allows querying results based on the output of another query. Subqueries are useful for breaking down complex problems into smaller, manageable steps.
Imagine a database with an employees
table and a departments
table. To find employees working in the department with the highest average salary, a subquery can determine the department first.
These return one row as output and are used with single-value comparison operators like =
, <
, or >
.
SELECT name, salary
FROM employees
WHERE salary > (
SELECT AVG(salary)
FROM employees
);
Explanation: The subquery calculates the average salary, and the main query retrieves employees earning above this average.
Name | Salary |
---|---|
John | 80000 |
Sarah | 90000 |
These return multiple rows and are used with operators like IN
, ANY
, or ALL
.
SELECT name
FROM employees
WHERE department_id IN (
SELECT department_id
FROM departments
WHERE location = 'New York'
);
Explanation: The subquery retrieves department IDs in New York. The main query fetches employee names in those departments.
Name |
---|
Alice |
Bob |
A correlated subquery uses values from the outer query and is executed repeatedly.
SELECT name, salary
FROM employees e1
WHERE salary > (
SELECT AVG(salary)
FROM employees e2
WHERE e1.department_id = e2.department_id
);
Explanation: For each employee, the subquery calculates the average salary in their department.
Subqueries can be nested to any level of complexity.
SELECT name
FROM employees
WHERE department_id = (
SELECT department_id
FROM departments
WHERE manager_id = (
SELECT manager_id
FROM employees
WHERE name = 'Alice'
)
);
Explanation:
The innermost query finds Alice’s manager, the middle query finds their department, and the outer query fetches employees in that department.
SELECT name,
(SELECT COUNT(*)
FROM projects
WHERE projects.employee_id = employees.id) AS project_count
FROM employees;
Name | Project Count |
---|---|
Alice | 3 |
Bob | 2 |
Used to filter data:
SELECT name
FROM employees
WHERE salary > (
SELECT AVG(salary)
FROM employees
);
Subqueries as derived tables:
SELECT department, AVG(salary)
FROM (
SELECT department_id, salary
FROM employees
) AS derived_table
GROUP BY department_id;
Filter aggregated data:
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id
HAVING AVG(salary) > (
SELECT AVG(salary)
FROM employees
);
=
, >
, <
, etc.Return a single value:
SELECT name,
(SELECT MAX(salary)
FROM employees) AS max_salary
FROM employees;
INSERT INTO high_earners (name, salary)
SELECT name, salary
FROM employees
WHERE salary > (
SELECT AVG(salary)
FROM employees
);
UPDATE employees
SET bonus = 5000
WHERE department_id = (
SELECT department_id
FROM departments
WHERE location = 'London'
);
DELETE FROM employees
WHERE id IN (
SELECT id
FROM terminated_employees
);
Subqueries and joins achieve similar outcomes but differ in structure and efficiency:
SELECT name
FROM employees
WHERE salary > (
SELECT AVG(salary)
FROM employees
WHERE department_id = (
SELECT department_id
FROM departments
WHERE location = 'Seattle'
)
);
Subqueries are a versatile feature in SQL, enabling users to perform complex operations with ease. Mastering subqueries allows you to write powerful, efficient, and readable queries. Happy Coding!❤️