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');

Question 5:Subqueries can be used in the FROM clause as a virtual table.

Question 6:In which of the following scenarios are subqueries particularly useful?

Srinivas Namala, author
About the author

Srinivas Namala

Software Engineer

Srinivas focuses on backend development, databases, systems, and the technologies used to build reliable server-side applications.

View LinkedIn profile ↗