← Back to all stagesStage 4
Stage 30: Subqueries
Concept
Implement nested SELECT statements that appear inside WHERE clauses, allowing one query's result to feed into another query's filter.
What It Teaches
- Nested execution: The executor creates a child executor for the subquery, runs it to completion, then uses its results in the outer query. This is recursive — a subquery can itself contain subqueries.
- Correlated vs uncorrelated subqueries: An uncorrelated subquery runs once (e.g.,
WHERE id IN (SELECT user_id FROM orders)). A correlated subquery runs once per outer row (e.g.,WHERE EXISTS (SELECT 1 FROM orders WHERE orders.user_id = users.id)). Correlated subqueries are dramatically slower. - IN operator:
WHERE id IN (subquery)materializes the subquery results into a set, then checks membership for each outer row. - EXISTS operator:
WHERE EXISTS (subquery)returns true if the subquery produces at least one row. It can short-circuit — stop as soon as the first row is found. - Scalar subqueries:
SELECT (SELECT COUNT(*) FROM orders) AS total— a subquery that returns exactly one value.
Learning Objectives
- Extend the parser to recognize subqueries in WHERE clauses.
- Implement
IN (SELECT ...)by materializing the subquery into an in-memory set. - Implement
EXISTS (SELECT ...)with early termination. - Handle correlated subqueries by re-executing the subquery for each outer row.
- (Stretch) Support scalar subqueries in the SELECT column list.
New SQL Syntax
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders);
SELECT * FROM users WHERE EXISTS (SELECT 1 FROM orders WHERE orders.user_id = users.id);