Subqueries & an Introduction to CTEs
Holding intermediate results: subqueries in FROM, WHERE, HAVING, SELECT and JOIN, the ICC points table solved, and CTEs with WITH.
The Crux in 60 Seconds
Some answers need an intermediate result
Average order value cannot come from AVG(sales) when an order has several rows. Sum per order first, then average that: 458, not 230.
A subquery can go anywhere
SELECT, FROM, WHERE, HAVING or JOIN. In FROM it needs an alias; used as a condition it does not. IN / NOT IN accept a list; comparison operators need one value.
Derive a second table from the first
Group the employee table by department to get average salary, then join it back. The ICC points table works the same way: flag, wrap, aggregate.
A CTE is a subquery moved to the top
WITH name AS (query) then a final SELECT. Same result, more readable, and one CTE can be reused several times.
Foundational Concepts & Comparisons
AVG(sales)
- Averages every row. Example: three rows, 1,800 total, average 600.
Average order value
- Sum per order id first (1,200 and 600), then average: 900.
Subquery in FROM
- Result acts as a virtual table; alias required, and you select columns from it in the outer query.
Subquery as a condition
- Only its result is compared, so no alias is needed.
IN / NOT IN
- Expect a list: one column, many rows allowed.
Greater than, less than
- Expect a single value, so the subquery must return one row and one column.
Inner vs outer query
- Inner: the query inside. Outer (main or final) query uses its result. Only the terms differ; it is still one idea.
Subquery vs CTE
- Very similar: the subquery moves into a
WITHblock with a name. Everything else stays the same.