Multiple CTEs in One Query
Chain several CTEs to compute department stats then rank departments by average salary.
Overview
You can define several CTEs in one WITH block, separated by commas, and even
reference earlier ones. This keeps complex queries readable by breaking them
into named, composable steps. Here we first aggregate per department, then rank
those aggregates.
The Query
Employees & Departments
Loading database engine...
Step-by-Step Breakdown
dept_stats— aggregates headcount and average salary per department.ranked— joins those stats to department names and ranks by average pay. It referencesdept_statsdefined just above it.- The final
SELECT *returns the composed result.
CTEs are not materialized (usually)
Most engines treat CTEs as inline views — they don't force intermediate storage, so they're primarily for readability, not performance.
Variations
Two CTEs for store: order totals then top customers:
Store (Customers/Orders/Products)
Loading database engine...
Common Mistakes
- Referencing a CTE before it's defined. You can only use a CTE after its
definition in the
WITHlist (or via later CTEs). - Forgetting the comma between CTEs. Separate definitions with commas; don't
repeat
WITH. - Name collisions. Each CTE needs a unique name within the block.