2.5Kпросмотров
22 апреля 2025 г.
questionScore: 2.7K
SQL. Оператор WITH — зачем он нам? Хочу сегодня поговорить с вами про такой инструмент в написании SQL-запросов, как WITH. 💡 Что это такое?
В общем и целом — это синтаксический сахар, который помогает понятным и читаемым образом получить необходимые данные из БД. Но всё по порядку. Простой пример: Допустим, у нас есть таблица sales: id employee_id amount 1 101 200 2 102 150 3 101 100
Задача: Сколько продаж сделал каждый сотрудник, если его сумма продаж выше 200? Вот как это можно сделать с помощью WITH: WITH sales_summary AS ( SELECT employee_id, SUM(amount) AS total_sales FROM sales GROUP BY employee_id
)
SELECT employee_id, total_sales
FROM sales_summary
WHERE total_sales > 200;
Что произошло?
Создана временная таблица sales_summary при помощи WITH, которую дальше можно использовать как обычную. А можно было проще? Да! Для этой задачи, честно говоря, можно было бы обойтись без WITH, и использовать HAVING: SELECT employee_id, SUM(amount) AS total_sales
FROM sales
GROUP BY employee_id
HAVING SUM(amount) > 200;
🔎 Но цель была — показать, как работает WITH, а не сделать самый короткий запрос. Когда WITH реально раскрывается: Представим чуть более сложную задачу:
Найти продажи по сотрудникам, затем взять топ-3 по сумме. WITH sales_summary AS ( SELECT employee_id, SUM(amount) AS total_sales FROM sales GROUP BY employee_id
)
SELECT *
FROM sales_summary
ORDER BY total_sales DESC
LIMIT 3; 🎯 Здесь HAVING уже не поможет — он не умеет работать с ORDER BY и LIMIT после агрегации.
А с WITH — всё наглядно и читаемо. А насколько WITH затратный для базы? Хороший вопрос. На практике, в PostgreSQL WITH раньше (до версии 12) всегда материализовался — сначала считался полностью, а потом уже использовался. Сейчас ситуация лучше — запрос может быть встроен обратно (inlined), если это безопасно. 💬 Так что да, иногда может быть небольшое ухудшение производительности. Но чаще — это не критично, особенно если ты выигрываешь в читаемости и логике. Когда WITH реально полезен: 1. Когда агрегат нужно переиспользовать в другом контексте (например, джойнить с другой таблицей)
2. Когда нужно сгруппировать данные, а потом делать с ними дополнительные действия
3. Когда запрос сложный, и хочется разбить его на понятные части
4. Когда есть несколько уровней агрегации Всем добра!
#sql #sql_with