Дашборд содержит две метрики на одних и тех же продажах: топ товаров по выручке за период и общая выручка за тот же период. Витрина обновляется ежедневно, и важно, чтобы фильтр по периоду был один и тот же для обеих цифр. Какой подход надёжнее защищает от рассинхронизации?
AСкопировать одинаковый фильтр по периоду в два разных подзапроса в
FROM salesBСчитать топ через
IN (SELECT ...), а общую выручку через EXISTS на тех же данныхCБазовый CTE
WITH base_sales AS (...) с фильтром по периоду и расчёт обоих чисел из негоDПоставить фильтр по периоду только в
SUM, а в группировке полагаться на JOIN без условий по датеПравильный ответ. CTE через
WITH позволяет определить «базовый слой» данных один раз и использовать его дальше в нескольких расчётах.Разбор
Когда период, сегмент или исключения повторяются, дублирование условий повышает риск ошибки: одну часть обновили, другую забыли. Базовый CTE фиксирует набор строк, на котором строятся все метрики, и делает запрос более детерминированным и проверяемым: можно сначала посмотреть, что попало в базу, и только потом агрегировать. Это особенно важно для дашбордов, где несколько чисел должны быть согласованы между собой.
Проверь себя · 1/3разбор после ответа
В отчёте нужно посчитать выручку по странам пользователей только по оплаченным заказам за период, причём шаг «оплаченные за период» используется ещё в трёх соседних метриках. Какой подход обычно делает запрос проверяемее и позволяет переиспользовать фильтрацию?
Ещё вопросы по теме «Подзапросы и 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» →