Нужно посчитать долю выручки каждого товара от общей выручки за один и тот же период. Какой вариант делает расчёт прозрачнее и избегает дублирования фильтра по периоду?
AВо внешнем
SELECT посчитать выручку по товару, а общий SUM взять скалярным подзапросом, повторив фильтр по периоду дважды.BСделать базовый CTE
WITH base AS (...) с фильтром по периоду, затем посчитать total и per_product из base, и в финальном SELECT делить per_product.product_amt на total.total_amt.CИспользовать коррелированный подзапрос в
WHERE, чтобы сразу оставить только товары с высокой долей.DУбрать фильтр по периоду из SQL и применить его уже после выгрузки данных.
Правильный ответ. Базовый CTE помогает один раз зафиксировать период и правила отбора, а затем строить от него и числитель, и знаменатель.
Разбор
Доля — это отношение двух агрегатов, которые должны быть рассчитаны на одном и том же наборе строк. Если фильтр копируется в два места, легко ошибиться (период или условия различатся) и получить неконсистентную метрику. При подходе с WITH base AS (...) вы явно задаёте общий источник данных и используете его повторно, поэтому логика становится детерминированной и проверяемой.
Проверь себя · 1/3разбор после ответа
Что является практическим преимуществом разбиения сложного запроса на шаги через
WITH по сравнению с несколькими вложенными подзапросами?Ещё вопросы по теме «Подзапросы и 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` корректно использует коррелированный подзапрос?
- Вы готовите дашборд: нужно (1) топ товаров по выручке за период и (2) общая выручка за тот же период. Какой вариант снижает риск, что фильтр по периоду рассинхронизируется между расчётами?
- Все вопросы по «Подзапросы и CTE» →