Читаемый SQL — это не «красота ради красоты», а способ быстрее находить ошибки, упрощать поддержку запросов и экономить время команды. Подзапросы и CTE помогают разбивать сложную логику на понятные блоки, но использовать их нужно осознанно.
Что такое подзапрос
Подзапрос — это запрос внутри другого запроса. Он помогает:
- отфильтровать данные
- посчитать промежуточные значения
- подготовить набор строк для
JOINилиWHERE
SELECT name
FROM employees
WHERE department_id IN (
SELECT id
FROM departments
WHERE region = 'EU'
);
Такой вариант подходит для локальной задачи, когда логика короткая и не требует повторного использования.
Что такое CTE
CTE (Common Table Expression) — это именованный временный результат, который объявляется через WITH. По сути, это способ сделать запрос более модульным.
WITH eu_departments AS (
SELECT id
FROM departments
WHERE region = 'EU'
)
SELECT name
FROM employees
WHERE department_id IN (
SELECT id FROM eu_departments
);
Почему CTE делает SQL читаемее ✍️
- логика делится на этапы
- каждый блок можно назвать по смыслу
- сложные
JOINи агрегации легче отлаживать - запрос проще читать коллегам и вам через месяц
Особенно полезны CTE в аналитике, отчетах и ETL-задачах, где в одном SQL много условий и преобразований.
Когда выбирать подзапрос, а когда CTE
Используйте подзапрос, если:
- он короткий
- используется один раз
- не усложняет чтение
Используйте CTE, если:
- запрос длинный и многоступенчатый
- промежуточную логику нужно переиспользовать
- важна понятная структура
- есть несколько уровней агрегации или фильтрации
Правила читаемого SQL с CTE и подзапросами ✅
- Давайте понятные имена:
active_users,monthly_revenue,filtered_orders - Один CTE — одна логическая задача
- Не делайте цепочку из 10+ CTE без необходимости
- Сначала фильтруйте лишние данные, потом объединяйте
- Не прячьте важную бизнес-логику в глубоко вложенные подзапросы
- Форматируйте запрос: переносы строк, отступы, выравнивание условий
Частая ошибка ⚠️
Пытаться переписать любой подзапрос в CTE «потому что так моднее». Не всегда это лучше. Иногда простой вложенный SELECT читается быстрее, чем несколько искусственно раздутых CTE.
Практический подход
Хороший SQL отвечает на вопрос: может ли другой разработчик понять логику за пару минут? Если нет — запрос стоит упростить. CTE здесь особенно полезен как инструмент декомпозиции, а подзапрос — как точечное решение.
Итог:
- подзапросы — для компактных задач
- CTE — для структуры и поддержки
- лучший выбор — тот, который делает запрос понятнее, а не просто «сложнее» 📊
👀 В конце дня выигрывает не самый хитрый SQL, а тот, который легко читать, проверять и менять.
Заодно посмотрите подборку каналов про IT — там много полезного по SQL, аналитике, backend и инженерной практике 🚀