Выбирать между WHERE и HAVING, понимая, что WHERE фильтрует строки до агрегации, а HAVING — группы после неё.
WHERE и HAVING: где фильтруются данные
Разница между WHERE и HAVING в потоке выполнения
WHERE и HAVING оба фильтруют, но на разных этапах. WHERE работает до агрегации — по строкам; HAVING — после, по результатам агрегата.
Lesson notes
Фильтр до и после группировки
SQL выполняет запрос в определённом порядке: сначала FROM (берём таблицу), потом WHERE (отбираем строки), затем GROUP BY (группируем), затем HAVING (отбираем группы), и только потом SELECT (формируем результат). Это значит, что в момент работы WHERE агрегаты ещё не посчитаны — база просто не знает, чему равен SUM(amount). Поэтому писать WHERE SUM(amount) > 200 — ошибка.
WHERE нужен для фильтрации отдельных строк по значениям в столбцах. Например, WHERE amount > 50 оставит только заказы дороже 50 рублей — ещё до любой группировки.
HAVING нужен для фильтрации уже готовых групп по результату агрегата. Например, HAVING SUM(amount) > 200 оставит только те города, у которых суммарный объём заказов превышает 200.
Разберём оба случая на таблице orders (Москва: 100,150,200; Казань: 50,80; Сочи: 300):
• WHERE amount > 50 → отбрасывает строки 50 из Казани; после GROUP BY Казань получит COUNT=1, SUM=80.
• HAVING SUM(amount) > 200 → после GROUP BY: Москва SUM=450 ✓, Казань SUM=130 ✗, Сочи SUM=300 ✓; в результате останутся Москва и Сочи.
Две типичные ошибки новичка: (1) написать WHERE SUM(amount) > 200 — синтаксическая ошибка, агрегат не может быть в WHERE; (2) написать HAVING без GROUP BY — почти всегда логическая ошибка, потому что без группировки нет групп для фильтрации.