A subquery lets you embed one SELECT inside another to pre-filter or aggregate data before the outer query runs.
Subqueries let you stage calculations—filters, aggregations, or joins—before the outer query. They reduce repeated logic, improve readability, and sometimes speed up execution by narrowing data early.
ClickHouse accepts subqueries in the FROM, JOIN, and SELECT clauses. Correlated subqueries in WHERE are not supported; use JOINs instead.
Wrap an inner SELECT in parentheses, give it an alias, and select from it as if it were a table.
SELECT c.id, c.name, stats.order_cntFROM ( SELECT id, name FROM Customers WHERE created_at >= today() - 7) AS cLEFT JOIN ( SELECT customer_id, count() AS order_cnt FROM Orders GROUP BY customer_id) AS statsON stats.customer_id = c.id;
A scalar subquery returns a single value. ClickHouse executes it once per query.
SELECT id, name, (SELECT avg(total_amount) FROM Orders) AS avg_order_valueFROM Customers
No. ClickHouse lacks correlated subquery support. Convert the logic to a JOIN or use WITH clauses.
Alias every subquery, compute only needed columns, and chain WITH expressions for readability. Test performance; sometimes moving logic into a materialized view is faster.
WITH simply names a subquery. Performance is identical; pick the one that improves readability.
Yes, but keep nesting shallow. Deep nesting complicates debugging and can hurt performance.
ClickHouse uses primary key ordering, not traditional indexes. A subquery benefits from the same data skipping indexes as any SELECT.