Introduction
Sometimes, solving a problem directly in SQL isn’t possible in a single step. You need to find something first — and use that result inside another query. That’s the power of subqueries. Also known as nested queries, subqueries allow one query to feed into another, like a conversation between clauses.
What is a Subquery?
A subquery is a SQL query inside another query. It’s usually enclosed in parentheses and can be used in SELECT, FROM, or WHERE clauses.
Sample Tables – students and results
CREATE TABLE students (
roll_no INT PRIMARY KEY,
name VARCHAR(50),
class VARCHAR(10)
);
INSERT INTO students VALUES
(1, 'Aarav Sharma', '10A'),
(2, 'Diya Iyer', '9B'),
(3, 'Sneha Patil', '10A'),
(4, 'Mehul Agarwal', '8C');
CREATE TABLE results (
roll_no INT,
subject VARCHAR(30),
marks INT
);
INSERT INTO results VALUES
(1, 'Maths', 85),
(2, 'Maths', 92),
(3, 'Maths', 78),
(4, 'Maths', 90);
1. Subquery in WHERE Clause
Let’s find students who scored more than the average marks in Maths:
SELECT name
FROM students
WHERE roll_no IN (
SELECT roll_no
FROM results
WHERE subject = 'Maths'
AND marks > (
SELECT AVG(marks)
FROM results
WHERE subject = 'Maths'
)
);
name
-------------
Diya Iyer
Mehul Agarwal
2. Subquery in SELECT Clause
Show each student's marks and how they compare to the average:
SELECT s.name, r.marks,
(SELECT AVG(marks) FROM results WHERE subject = 'Maths') AS avg_marks
FROM students s
JOIN results r ON s.roll_no = r.roll_no
WHERE r.subject = 'Maths';
name | marks | avg_marks
----------------+-------+-----------
Aarav Sharma | 85 | 86.25
Diya Iyer | 92 | 86.25
Sneha Patil | 78 | 86.25
Mehul Agarwal | 90 | 86.25
3. Subquery in FROM Clause
Let’s first calculate average marks per student, then filter only those with more than 80:
SELECT t.roll_no, t.avg_marks
FROM (
SELECT roll_no, AVG(marks) AS avg_marks
FROM results
GROUP BY roll_no
) AS t
WHERE t.avg_marks > 80;
roll_no | avg_marks
--------+-----------
1 | 85.0
2 | 92.0
4 | 90.0
4. Correlated Subqueries
These refer to columns from the outer query. Example: Get students whose marks are higher than the class average.
SELECT name
FROM students s
WHERE EXISTS (
SELECT 1
FROM results r
WHERE r.roll_no = s.roll_no
AND r.marks > (
SELECT AVG(marks)
FROM results
)
);
Summary
Subqueries allow you to solve problems by breaking them into parts. Whether it's filtering, calculating, or comparing — using one query inside another lets you add intelligence and precision to your SQL logic.
What’s Next?
Next up: Common Table Expressions (CTEs) — an advanced but readable way to structure complex queries more cleanly than subqueries.

About the authorSrinivas Namala
Software Engineer
Srinivas focuses on backend development, databases, systems, and the technologies used to build reliable server-side applications.
View LinkedIn profile ↗