Build a query in steps
A CTE is one named step. Many small steps are easier to read than one big query.
A long query that does everything at once is hard to read. You can split it into small steps and give each step a name.
A CTE (common table expression) is one named step. You write it with WITH. The main query then uses the name like a table.
This query names the paid orders, then reads from that name:
| order_id | customer_id | status | amount | order_date |
|---|---|---|---|---|
| 101 | 1 | paid | 40.00 | 2026-01-03 |
| 102 | 1 | paid | 25.00 | 2026-01-10 |
| 103 | 2 | refunded | 60.00 | 2026-01-11 |
| 104 | 3 | paid | 15.50 | 2026-01-15 |
| 105 | 3 | pending | NULL | 2026-01-20 |
| 106 | 4 | paid | 80.00 | 2026-01-21 |
WITH paid_orders AS (
SELECT order_id, customer_id, amount
FROM orders
WHERE status = 'paid'
)
SELECT order_id, customer_id, amount
FROM paid_orders
ORDER BY order_id;| order_id | customer_id | amount |
|---|---|---|
| 101 | 1 | 40.00 |
| 102 | 1 | 25.00 |
| 104 | 3 | 15.50 |
| 106 | 4 | 80.00 |
A CTE lives only while this one query runs. The database does not save it.
What you will learn
You met subqueries in chapter 2. Here you use them with CTEs. You build bigger queries that you can still check by hand.
In this chapter, you learn to:
- Chain CTEs, and check one step at a time.
- Use a subquery that gives one value.
- Use a subquery that looks at the row it is checking.
- Put a subquery in FROM.
- Clean a column once, and walk a tree with a recursive CTE.
- Keep a query easy to read.
The examples use the same shop as chapters 1 to 3. The recursive section adds one small table, with its own rows.
