A Common Table Expression (CTE) defines a temporary, named result set inside a WITH clause that can be referenced within a single MySQL statement.
A CTE creates a temporary, readable alias for a subquery. It simplifies complex joins, improves readability, and enables recursion—all without persisting data beyond the current statement.
CTEs improve clarity, allow multiple references to the same derived set, and make recursive logic possible. They also keep business logic close to the final query, easing maintenance.
The WITH clause precedes the main query. Each CTE is named, may include an optional column list, and is terminated by a comma if another CTE follows.
WITH cte_name (col1, col2) AS (
SELECT ...
)
SELECT ... FROM cte_name;
WITH RECURSIVE cte_name AS (
SELECT ... -- anchor
UNION ALL
SELECT ... FROM cte_name ... -- recursive
)
SELECT * FROM cte_name;
Separate each CTE with a comma. The final SELECT can reference any preceding CTE.
See the example query below to calculate each customer’s lifetime spend and return only those above $1,000.
Keep each CTE focused on one task, name CTEs descriptively, and avoid unnecessary recursion. Always test performance against equivalent subqueries.
Review the pitfalls section below to avoid scope, ordering, and performance issues.
CTEs are available starting in MySQL 8.0. Prior versions do not recognize the WITH clause.
Yes. Use the CTE to define rows to update, then issue an UPDATE that joins or references the CTE.
MySQL materializes CTEs as temporary tables when needed. The optimizer may inline them when beneficial. Memory or disk usage depends on size and configuration.