Chapter 12: Subqueries and Nested Queries

A subquery (also called a nested query) is simply a SELECT statement inside another SELECT statement. It’s like asking a question, and inside the answer you ask another smaller question.

Subqueries make SQL incredibly powerful because they let you:

  • Compare values with results from another query
  • Filter rows based on complex logic
  • Create temporary result sets on the fly

Today we’re going to master the three main places you can put a subquery:

  1. In the SELECT clause (returns a single value)
  2. In the FROM clause (creates a temporary table)
  3. In the WHERE clause (most common – filtering)

We’ll also cover correlated subqueries (the subquery depends on the outer query) and the super-useful EXISTS / NOT EXISTS operators.

We’ll continue using our bookshop database with authors and books tables.

Sample Data Reminder (books table – a bit more data for good examples)

book_id title author_id price stock category published_year
1 The Room on the Roof 1 250.00 45 Fiction 1956
2 2 States 3 299.00 120 Fiction 2009
3 The White Tiger 2 399.00 35 Fiction 2008
4 Wise and Otherwise 5 199.00 80 Non-Fiction 2002
5 The Immortals of Meluha 4 349.00 65 Fantasy 2010
6 The Blue Umbrella 1 180.00 50 Children 1980
7 Malgudi Days 6 220.00 90 Fiction 1943
8 Train to Pakistan 7 280.00 60 Historical 1956
9 Half Girlfriend 3 280.00 95 Fiction 2014
10 The Palace of Illusions 8 450.00 25 Mythology 2008

1. Subqueries in the SELECT Clause (Scalar Subquery)

A subquery in SELECT must return exactly one value (one row, one column).

Example – Show each book and the average price of all books:

SQL

Result (every row shows the same avg):

title price avg_book_price
The Room on the Roof 250.00 292.60
2 States 299.00 292.60

More useful – Show each book and the average price of books by the same author:

SQL

This is a correlated subquery — it depends on the outer row (b.author_id).

2. Subqueries in the FROM Clause (Derived Table)

You treat the result of a subquery like a temporary table.

Example – Find the top 3 most expensive categories:

SQL

Result might be:

category avg_price total_books
Mythology 450.00 1
Fantasy 349.00 1
Fiction 289.60 5

Pro Tip: Always give the subquery an alias (like AS category_summary) — some databases require it.

3. Subqueries in the WHERE Clause (Most Common)

This is where subqueries shine the most!

Example A – Books more expensive than the average price:

SQL

Example B – Books by authors who have written more than 1 book:

SQL

Result: Books by Ruskin Bond (author 1) and Chetan Bhagat (author 3)

4. Correlated Subqueries – The Subquery Knows About the Outer Row

A correlated subquery references columns from the outer query — it runs once for each row of the outer query.

Example – Find books that are more expensive than the average price of their own author:

SQL

Result: Books that are above their author’s personal average price.

Important: Correlated subqueries can be slower because they run repeatedly — but for small datasets they’re fine and very readable.

5. EXISTS / NOT EXISTS – Check for Existence (Very Efficient!)

Instead of comparing values, you just check if any row exists that matches a condition.

Syntax:

SQL

Example A – Authors who have at least one book:

SQL

Example B – Authors who have NO books:

SQL

Result: Chitra Banerjee, Vikram Seth, etc.

Why use EXISTS instead of IN?

  • EXISTS stops as soon as it finds one match → usually faster
  • Works well with correlated subqueries
  • Handles NULLs better in some cases

Full Realistic Business Example

SQL

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *