SQL Subquery Explained for Beginners (With Examples)
SQL subquery explained for beginners: learn what a subquery is and how to use it in WHERE, FROM and SELECT with simple, copy-paste examples you can run.
SQL subquery explained for beginners: learn what a subquery is and how to use it in WHERE, FROM and SELECT with simple, copy-paste examples you can run.
What is a SQL subquery? A subquery is a query written inside another query. The inner query runs first and hands its answer to the outer query. If you have ever thought "I need to find one value first, and then use it to filter my results," a subquery is the tool for that job.
This guide is for absolute beginners. We define every term, use one small example table, and explain each query line by line. You should already know basic SELECT and WHERE.
Imagine a small shop. It has a table called products. A table is a grid of data. Each row is one product and each column is one fact about it.
CREATE TABLE products (
id INT,
name VARCHAR(50),
category VARCHAR(50),
price DECIMAL(6,2)
);
INSERT INTO products VALUES
(1, 'Notebook', 'Paper', 4.50),
(2, 'Pen', 'Writing', 1.20),
(3, 'Backpack', 'Bags', 35.00),
(4, 'Marker', 'Writing', 2.80),
(5, 'Desk Lamp', 'Home', 22.00);The first statement builds the table with four columns. The second adds five rows. Run both in any SQL tool, such as PostgreSQL's psql or MySQL.
Say you want every product that costs more than the average price. You need two steps. First, find the average. Second, list the products above it. Without a subquery you would run the average query, copy the number, and paste it into a second query. That breaks as soon as the data changes.
SELECT AVG(price) FROM products;AVG is an aggregate function. It adds up all the prices and divides by the number of rows. Here the answer is 13.10. Now we let SQL do the copy-and-paste for us.
SELECT name, price
FROM products
WHERE price > (SELECT AVG(price) FROM products);Line 1 picks the columns we want to see. Line 2 says which table to read. Line 3 filters the rows. The part inside the brackets is the subquery. SQL runs it first, gets 13.10, and then treats line 3 as WHERE price > 13.10. The result is Backpack and Desk Lamp.
Two rules to remember: a subquery is always wrapped in round brackets, and it must return what the outer query expects. Here the outer query expects one single number, and AVG gives exactly one.
Sometimes the inner query returns many values instead of one. In that case use IN, which checks whether a value is in a list. Suppose we have a second table of categories that are on sale.
CREATE TABLE sale_categories (category VARCHAR(50));
INSERT INTO sale_categories VALUES ('Writing'), ('Bags');
SELECT name, category
FROM products
WHERE category IN (SELECT category FROM sale_categories);The first line creates a one-column table. The INSERT adds two categories. The final query asks for products whose category appears in the list returned by the subquery. The result is Pen, Backpack and Marker. If you used = here instead of IN, you would get an error, because = can only compare against one value.
You can also use a subquery as a temporary table. This is called a derived table. You must give it a name, called an alias.
SELECT category, avg_price
FROM (
SELECT category, AVG(price) AS avg_price
FROM products
GROUP BY category
) AS category_prices
WHERE avg_price > 3;The inner query groups products by category and works out the average price of each. AS avg_price gives that column a friendly name. The outer query treats the result like a normal table called category_prices and keeps only the rows where avg_price is above 3. Most databases require the alias after the closing bracket, so do not forget it.
SELECT
name,
price,
price - (SELECT AVG(price) FROM products) AS diff_from_avg
FROM products;Here the subquery sits inside the column list. For each product it shows how far the price is from the average. The subquery returns a single value, so SQL can subtract it from every row.
| Location | What the subquery returns | Typical use |
|---|---|---|
| WHERE with > < = | One value | Compare to an average or maximum |
| WHERE with IN | A list of values | Match against another table |
| FROM | A whole table | Pre-calculate groups, then filter |
| SELECT | One value per row | Add a calculated column |
A JOIN combines two tables side by side. A subquery asks a question and uses the answer. Many problems can be solved either way. As a beginner, pick whichever one you can read more easily. If you need columns from both tables in the result, use a JOIN. If you only need to filter by a calculated value or a list, a subquery is often simpler.
Try them one at a time and read the result before moving on. Changing a number in the table and re-running the query is a great way to see the subquery react.
A subquery is a SELECT statement placed inside another SQL statement, wrapped in round brackets. The database runs the inner query first and passes its result to the outer query. It is also called a nested query or inner query.
A JOIN puts columns from two tables side by side in one result. A subquery computes a value or list that the outer query uses, usually for filtering. Many tasks can be done with either, so choose the one that is easier to read.
Yes, but then you must use an operator that accepts a list, such as IN. Operators like = and > expect a single value and will give an error if the subquery returns several rows.
For small tables and beginner projects you will not notice any difference. Modern databases are good at optimising them. Worry about speed only when you work with very large data.
You can use one in the WHERE clause, the FROM clause, and the SELECT list. Each place expects a different kind of result: a value, a table, or one value per row.
New to filtering? Read our guide on the IN and BETWEEN operators, which pairs perfectly with subqueries.
Read the IN and BETWEEN guideWant help building a real database-powered product? Talk to the Fepiq team.
Contact FepiqOccasional, no-fluff notes on shipping modern software — startups, automation, Laravel, Shopify and more. No spam, unsubscribe anytime.
Keep reading
What is an arrow function in JavaScript? Learn the => syntax step by step with simple examples, plain English and a quick practice quiz. Start here.
Learn what PHP cookies are and how to set, read and delete them with setcookie(). Simple examples and line-by-line explanations for absolute beginners.
Let's build something
Book a free discovery call. We'll listen, ask sharp questions, and send you a proposal within 3 business days.