Данные, которых у вас ещё нет
Специалисты по SQL иногда работают с однотипными задачами. Есть два подхода: писать похожие запросы каждый раз заново или стараться оптимизировать работу.
Представьте, что вас попросили найти двадцать клиентов с самой большой суммарной стоимостью покупок за последний месяц. Эти пользователи получат специальные промокоды. Задача несложная: нужно сгруппировать данные по клиенту и посчитать сумму выручки. Список идентификаторов нужных пользователей готов.
А что, если проверить, сколько эти пользователи тратили в течение года? Без проблем: снова считаем выручку на клиента, но теперь ограничиваем выгрузку годом и идентификаторами пользователей, отобранными на прошлом этапе.
Условие для среза будет выглядеть примерно так:
SQL
Эту задачу вы решили, но похожие запросы придётся составлять каждый месяц, чтобы рассылать новые промокоды. В следующем месяце список самых платящих клиентов наверняка поменяется — придётся исправлять и запрос с подсчётами за год. Можно переписывать запросы каждый раз, но вдруг количество отбираемых клиентов вырастет до 50 или даже до 100?
Заранее получить список с идентификаторами клиентов не получится, но он точно будет сформирован другим запросом — с расчётом выручки по клиентам. Оптимизировать такую задачу можно подзапросом, но добавить его нужно не во
FROM, а в WHERE.Подзапросы в WHERE
Подзапрос в
WHERE, в отличие от подзапроса во FROM, не совсем линейный.Чтобы объяснить эту особенность, вернёмся к декомпозиции. Когда вы пишете подзапрос во
FROM, вы решаете большую задачу поэтапно с помощью задач поменьше. Поэтому, если убрать какой-либо элемент из решения, код не сработает. Подзапросы в
WHERE устроены не так: они дополняют основной запрос, уточняя нужный срез.Запрос с формированием списка самых платящих клиентов можно поместить в подзапрос в
WHERE. Расчёты повторять не придётся, останется только уточнить месяц для среза.