CTE (WITH): делаем сложное читаемым
CTE (Common Table Expression), это именованный подзапрос, объявленный в начале. Он делает сложные запросы понятными.
Зачем CTE
Сравни два одинаковых запроса:
Без CTE, трудно читать:
SELECT c.name, t.total
FROM (
SELECT customer_id, SUM(amount) AS total
FROM orders
WHERE status = 'completed'
GROUP BY customer_id
) t
JOIN customers c ON t.customer_id = c.id
WHERE t.total > 10000;
С CTE, читается как текст:
WITH customer_totals AS (
SELECT customer_id, SUM(amount) AS total
FROM orders
WHERE status = 'completed'
GROUP BY customer_id
)
SELECT c.name, ct.total
FROM customer_totals ct
JOIN customers c ON ct.customer_id = c.id
WHERE ct.total > 10000
ORDER BY ct.total DESC;
Несколько CTE
Можно объявить несколько CTE и ссылаться на предыдущие:
WITH
-- Шаг 1: Выручка по менеджерам
manager_revenue AS (
SELECT manager_id, SUM(amount) AS revenue
FROM deals
WHERE status = 'won'
GROUP BY manager_id
),
-- Шаг 2: Рейтинг
manager_rank AS (
SELECT
manager_id,
revenue,
RANK() OVER (ORDER BY revenue DESC) AS rnk
FROM manager_revenue
)
-- Итог: топ-5
SELECT m.name, mr.revenue, mr.rnk
FROM manager_rank mr
JOIN managers m ON mr.manager_id = m.id
WHERE mr.rnk <= 5;
Каждый CTE, это шаг. Читаешь сверху вниз и понимаешь логику.
CTE vs подзапрос vs временная таблица
| Инструмент | Когда использовать |
|---|---|
| Подзапрос | Простое вложение, используется один раз |
| CTE | Сложная логика, несколько шагов, читаемость важна |
| Временная таблица | Очень большие данные, нужна материализация |
Рекурсивные CTE
CTE умеют ссылаться на себя, это позволяет работать с иерархиями (орг. структура, категории дерево). Это продвинутая тема, но знать что такое существует полезно.
💡 Главная мысль: CTE, лучший способ писать сложные запросы. Разбивай логику на именованные шаги. Код читается как описание задачи.