






SQL Subqueries
Using a Query Inside Another Query
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.
Types of Subqueries
- Scalar Subquery – returns a single value
- Row Subquery – returns one row with multiple columns
- Table Subquery – returns multiple rows and columns (used in FROM clause)
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
)
);
Best Practices
- Use subqueries for readability and step-wise logic.
- Try CTEs (Common Table Expressions) for complex nested queries.
- Avoid over-nesting — too many levels may impact performance.
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.
QUIZ
Question 1:What is a subquery in SQL?
Question 2:A subquery must always return only one row to be valid.
Question 3:Which of the following are valid uses of subqueries?
Question 4:What does this query return?
SELECT name FROM students WHERE roll_no IN (SELECT roll_no FROM results WHERE grade = 'A');
SELECT name FROM students WHERE roll_no IN (SELECT roll_no FROM results WHERE grade = 'A');