All SQL topics
SQL TOPIC

SQL WITH (CTE): break a question into steps

A common table expression names an intermediate result so a hard question becomes a few readable steps.

WITH monthly AS (SELECT …) SELECT … FROM monthly works like creating a temporary table for one query.

Chain several CTEs, separated by commas, to stage the logic: first clean, then aggregate, then compare.

Worked example

What was paid revenue per month, and which months were above €3,000?

WITH monthly AS (
  SELECT strftime('%Y-%m', invoice_date) AS month, SUM(amount) AS revenue
  FROM invoices
  WHERE status = 'paid'
  GROUP BY month
)
SELECT month, revenue
FROM monthly
WHERE revenue > 3000
ORDER BY month
LIMIT 6;
Result on the sample data
monthrevenue
2025-124739
2026-013989
2026-025382
2026-035333
2026-045731
2026-054932

Common mistakes

  • Forgetting the comma between two CTEs.
  • Ending the CTE without a final SELECT that uses it.