Вы готовите дашборд: нужно (1) топ товаров по выручке за период и (2) общая выручка за тот же период. Какой вариант снижает риск, что фильтр по периоду рассинхронизируется между расчётами?
AСкопировать одинаковый фильтр в два разных подзапроса внутри
SELECT.BСделать CTE
WITH base_sales AS (...) с фильтром по периоду и использовать его и для расчёта топа (через GROUP BY), и для общего SUM.CСчитать топ товаров через
IN, а общую выручку — через EXISTS.DСделать фильтр только в одном месте, а в другом надеяться на
JOIN без условий.Правильный ответ. CTE через
WITH позволяет определить «базовый слой» данных один раз и использовать его дальше в нескольких расчётах.Разбор
Когда период/сегмент/исключения повторяются, дублирование условий повышает риск ошибки: одну часть обновили, другую забыли. Базовый CTE фиксирует набор строк, на котором строятся все метрики, и делает запрос более детерминированным и проверяемым: можно сначала посмотреть, что попало в базу, и только потом агрегировать.
Проверь себя · 1/3разбор после ответа
Нужно выбрать заказы, у которых
amount выше среднего amount по тому же пользователю. Какой вариант WHERE корректно использует коррелированный подзапрос?Ещё вопросы по теме «Подзапросы и CTE»
- В отчёте нужно посчитать выручку по странам пользователей только по оплаченным заказам за период. Какой подход обычно делает запрос более читаемым и позволяет переиспользовать шаг фильтрации?
- Вы выбираете пользователей, у которых есть хотя бы один платеж. В таблице `payments` поле `user_id` иногда бывает `NULL` (например, анонимные платежи). Почему в такой ситуации часто предпочитают `EXISTS`, а не `IN`?
- Вы пишете `SELECT u.user_id, (SELECT order_id FROM orders o WHERE o.user_id = u.user_id) AS last_order_id FROM users u`. Что может пойти не так и как исправить, чтобы подзапрос стал скалярным?
- Нужно выбрать заказы, у которых `amount` выше среднего `amount` по тому же пользователю. Какой вариант `WHERE` корректно использует коррелированный подзапрос?
- Вы ищете пользователей без заказов. Почему запрос `SELECT u.user_id FROM users u WHERE u.user_id NOT IN (SELECT o.user_id FROM orders o)` может вернуть 0 строк и какой подход безопаснее?
- Все вопросы по «Подзапросы и CTE» →