Короткий ответ
CTE объявляется перед основным запросом конструкцией WITH имя AS (...). Именованный результат доступен ниже как таблица и помогает представить обработку данных последовательностью понятных шагов.
Как это работает подробнее
Несколько CTE перечисляются через запятую, причём следующий шаг может ссылаться на предыдущий. Это удобно для схемы: отфильтровать строки, агрегировать, добавить бизнес-правило, сформировать финальный вывод.
CTE — часть одного SQL-запроса, а не постоянная или автоматически индексируемая таблица. Современный оптимизатор может встроить его в план либо материализовать в зависимости от диалекта и настроек.
Пример кода
query.sql
WITH monthly_sales AS (
SELECT DATE_TRUNC('month', order_date) AS month_start,
SUM(amount) AS total_amount
FROM orders
GROUP BY DATE_TRUNC('month', order_date)
)
SELECT month_start, total_amount
FROM monthly_sales
WHERE total_amount > 100000
ORDER BY month_start;Что использовать на практике
- Давайте смысловые имена. Название вроде
monthly_salesлучше техническогоcte1. - Один шаг — одна задача. Не разбивайте простой запрос на множество CTE без выигрыша в читаемости.
Подводные камни
- Не гарантированный кэш. Повторная ссылка на CTE не всегда означает однократное вычисление.
- Граница оптимизации. В некоторых версиях и диалектах материализация может ухудшить производительность; проверяйте
EXPLAIN.