A Common Table Expression (CTE) defines a temporary, named result set you can reference within a single MariaDB statement, simplifying complex queries and enabling recursion.
A CTE is a temporary, named result set created with the WITH clause and available only for the statement that follows. It helps you break large queries into readable blocks and can be recursive.
CTEs improve readability, allow multiple references to the same derived data, enable recursion, and make debugging easier.They seldom change performance but greatly aid maintenance.
Define the CTE with WITH, list column names if needed, supply a SELECT, then query it like a table.
WITH recent_customers AS (
SELECT id, name, created_at
FROM Customers
WHERE created_at > NOW() - INTERVAL 30 DAY
)
SELECT * FROM recent_customers ORDER BY created_at DESC;
Separate CTE blocks with commas.Each CTE can refer to those defined before it.
WITH recent_orders AS (
SELECT id, customer_id, total_amount
FROM Orders
WHERE order_date > NOW() - INTERVAL 7 DAY
),
high_value AS (
SELECT * FROM recent_orders WHERE total_amount > 500
)
SELECT c.name, hv.total_amount
FROM high_value hv
JOIN Customers c ON c.id = hv.customer_id;
Add the RECURSIVE keyword, supply an anchor SELECT, then a UNION ALL with the recursive member that references the CTE name.
WITH RECURSIVE date_series AS (
SELECT DATE(NOW()) AS d
UNION ALL
SELECT d + INTERVAL 1 DAY FROM date_series WHERE d < DATE(NOW()) + INTERVAL 6 DAY
)
SELECT d FROM date_series;
Keep each CTE focused, name them descriptively, avoid unnecessary recursion, and always test performance with EXPLAIN.
No.A CTE’s data exists only during the statement, inherits indexes from source tables, and cannot be indexed itself.
.
Yes. The planner reuses the result without recomputing, saving you from repeating logic.
By default, MariaDB inlines CTEs like views. Use MATERIALIZED hints (10.5+) when you need a separate temp table.
No. A CTE only supplies read-only result sets, but you can run modifying statements that reference CTE data.