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