A ClickHouse CTE (WITH clause) defines a temporary result set you can reference multiple times within a single query, improving readability and performance.
CTEs let you name a sub-query once and reuse it, avoiding repeated code and enabling step-by-step logic in complex reports.
Place a WITH clause before the main SELECT. Give each sub-query an alias and end the list with the final SELECT that uses those aliases.
Yes—separate every CTE with a comma. Each CTE can reference earlier ones, but not later ones.
No. ClickHouse only supports non-recursive (single-pass) CTEs, so hierarchical data needs other techniques.
Use a CTE when the intermediate result appears more than once, when the logic benefits from naming, or when you want to simplify long SELECT statements for readability.
The example below calculates each customer’s total spend and average order value using two CTEs, then joins them for final output.
WITH customer_totals AS (
.
SELECT customer_id,
SUM(total_amount) AS lifetime_spend
FROM Orders
GROUP BY customer_id
),
order_stats AS (
SELECT customer_id,
COUNT(*) AS orders_placed,
AVG(total_amount) AS aov
FROM Orders
GROUP BY customer_id
)
SELECT c.id,
c.name,
ct.lifetime_spend,
os.orders_placed,
os.aov
FROM Customers AS c
JOIN customer_totals AS ct ON ct.customer_id = c.id
JOIN order_stats AS os ON os.customer_id = c.id
ORDER BY ct.lifetime_spend DESC;
Keep CTEs narrow—select only required columns. Give intuitive alias names. Profile execution plans: ClickHouse inlines CTEs, so performance is similar to sub-queries, but readability gains remain.
A missing comma between CTEs or omitting the final SELECT triggers syntax errors. Expecting recursive behavior also leads to confusion—ClickHouse stops at one evaluation pass.
No—ClickHouse inlines CTEs during query planning, so performance matches equivalent sub-queries. Use CTEs for readability, not speed.
Yes, but only if the referenced CTE appears earlier in the WITH list. Order matters.
CTE results live only for the duration of the statement and are not materialized unless ClickHouse’s optimizer decides; they vanish after execution.