A topic in the Open Knowledge Graph — a free, open map of 15,290 topics and the order to learn them in.

SQL Subqueries and CTEs

College Depth 72 in the knowledge graph I know this Set as goal
1topic build on this
335prerequisites beneath it
See this on the map →
SQL: SELECT Statement and Basic QueriesSQL Aggregation and GROUP BY+2 moreCommon Table Expressions (CTEs): WITH Clause
SQL subqueries CTE WITH correlated subquery nested queries

Core Idea

Subqueries are SELECT statements nested inside another query, used in WHERE, FROM, or SELECT clauses to compute intermediate results. Correlated subqueries reference columns from the outer query and re-execute for each outer row, enabling row-by-row comparisons against aggregated or filtered data. Common Table Expressions (CTEs) using the WITH clause improve readability by naming intermediate results and support recursive queries for hierarchical data. Subqueries and CTEs are often interchangeable with joins, with different performance and readability implications.

How It's Best Learned

Convert a JOIN-based query to an equivalent subquery and back — this builds intuition for when each form is clearer. Practice correlated subqueries for patterns like 'find all employees earning above their department's average salary.'

Common Misconceptions

Explainer

You already know how to SELECT, JOIN, and aggregate data. Subqueries let you compose these operations — embedding one query inside another to build complex results step by step. The simplest form is a scalar subquery in a WHERE clause: `SELECT * FROM employees WHERE salary > (SELECT AVG(salary) FROM employees)`. The inner query runs first, computes a single value (the average salary), and the outer query uses that value as a filter. This is something you cannot do with a plain WHERE clause alone, because the comparison target itself requires a computation.

Subqueries become more powerful — and more subtle — when placed in the FROM clause or when they are correlated. A subquery in the FROM clause acts as a temporary table (called a derived table): `SELECT dept, avg_sal FROM (SELECT department AS dept, AVG(salary) AS avg_sal FROM employees GROUP BY department) AS dept_stats WHERE avg_sal > 80000`. The inner query creates a result set, the outer query filters it. A correlated subquery, by contrast, references a column from the outer query and re-executes for each outer row: `SELECT e.name FROM employees e WHERE e.salary > (SELECT AVG(salary) FROM employees WHERE department = e.department)`. This finds employees earning above their own department's average — something that requires the inner query to "know" which department the outer row belongs to.

Common Table Expressions (CTEs) offer a cleaner syntax for the same idea. Instead of nesting queries, you name intermediate results with `WITH`: `WITH dept_avg AS (SELECT department, AVG(salary) AS avg_sal FROM employees GROUP BY department) SELECT e.name, d.avg_sal FROM employees e JOIN dept_avg d ON e.department = d.department WHERE e.salary > d.avg_sal`. The logic is identical to the correlated subquery version, but the CTE makes the data flow explicit and readable. CTEs also support recursion — a `WITH RECURSIVE` CTE can traverse hierarchical data like organizational charts or category trees by repeatedly joining a result set with itself.

One important practical note: subqueries, CTEs, and joins are often interchangeable, and the query optimizer frequently rewrites one form into another internally. A correlated subquery that looks like it would execute once per row is often transformed into a join by the optimizer. This means you should generally write whichever form is clearest to read and maintain, then check the execution plan only if performance is a concern. The exception is the `NOT IN` versus `NOT EXISTS` distinction — when the subquery can return NULLs, `NOT IN` produces unexpected results due to SQL's three-valued logic, so `NOT EXISTS` is the safer choice.

Practice Questions 5 questions

Prerequisite Chain

Understanding ZeroThe Number ZeroCounting to FiveCounting to 10Counting to 20Counting a Set of Objects Up to 20Cardinality: The Last Number CountedMatching Numerals to QuantitiesSubitizing Small QuantitiesAddition Within 10Number Bonds to 10Addition Within 20Doubles and Near DoublesDoubles Facts Within 10Near Doubles Facts Within 20Mental Math Strategies for AdditionMental Math: Adding and Subtracting TensAddition Within 100Repeated Addition as MultiplicationMultiplication as Equal GroupsMultiplication: ArraysBasic Multiplication Facts (0s, 1s, 2s, 5s, 10s)Multiplication Facts Within 100Division as Equal SharingDivision as Grouping (Measurement Division)Division: Grouping (Repeated Subtraction) ModelDivision: Fair Sharing ModelDivision as Equal SharingDivision as GroupingBasic Division FactsDivision Facts Within 100Multiplication and Division Fact FamiliesRelationship Between Multiplication and DivisionDivision Facts as Inverse of MultiplicationRemainders and Quotients in DivisionDivision Word ProblemsMulti-Step Word ProblemsSolving Multi-Step Word ProblemsMultiplication Word ProblemsDivision Word ProblemsIntroduction to Long DivisionFactors and MultiplesPrime and Composite NumbersEquivalent FractionsRelating Fractions and DecimalsDecimal Place ValueIntegers and the Number LineComparing and Ordering IntegersAbsolute ValueAdding IntegersSubtracting IntegersMultiplying IntegersIntroduction to ExponentsOrder of OperationsInteger Order of OperationsVariable ExpressionsThe Distributive PropertyVariables and Expressions ReviewIntroduction to PolynomialsAdding and Subtracting PolynomialsMultiplying PolynomialsFactorialPermutationsCombinationsCounting Principles: Addition and Multiplication RulesIntroduction to Graph TheoryPropositional Logic FoundationsLogical EquivalencesSet Operations: Union, Intersection, and ComplementRelational AlgebraSQL: SELECT Statement and Basic QueriesSQL JoinsSQL Subqueries and CTEs

Longest path: 73 steps · 335 total prerequisite topics

Prerequisites (4)

Leads To (1)