Ответ
Ключевое отличие заключается в моменте применения фильтрации в порядке выполнения SQL-запроса.
WHEREфильтрует строки до группировки (операцияGROUP BY). Он работает с отдельными записями исходной таблицы.HAVINGфильтрует строки после группировки. Он работает с агрегированными результатами (группами), созданнымиGROUP BY.
Порядок выполнения SQL-запроса (упрощенно)
FROM/JOIN(определение таблиц)WHERE(фильтрация строк на этом этапе)GROUP BY(группировка отфильтрованных строк)HAVING(фильтрация сгруппированных результатов)SELECT(выбор полей)ORDER BY(сортировка)
Практические примеры
Пример 1: WHERE (фильтрация до группировки)
"Найти среднюю зарплату по отделам, но только для сотрудников, работающих в компании больше года."
SELECT DepartmentId, AVG(Salary) as AvgSalary FROM Employees WHERE DATEDIFF(year, HireDate, GETDATE()) > 1 -- Фильтр применяется к КАЖДОМУ сотруднику GROUP BY DepartmentId;Здесь
WHEREсначала отсеивает всех сотрудников со стажем меньше года, и только затем оставшиеся записи группируются по отделам для расчета средней зарплаты.
Пример 2: HAVING (фильтрация после группировки)
"Найти отделы, в которых средняя зарплата превышает 75000."
SELECT DepartmentId, AVG(Salary) as AvgSalary FROM Employees GROUP BY DepartmentId HAVING AVG(Salary) > 75000; -- Фильтр применяется к РЕЗУЛЬТАТУ агрегации (к группам)Здесь сначала вычисляется средняя зарплата для каждого отдела, а затем
HAVINGотбрасывает те группы (отделы), где это среднее значение не превышает 75000.
Пример 3: Совместное использование WHERE и HAVING
"Найти отделы, где средняя зарплата действующих сотрудников превышает 80000."
SELECT DepartmentId, AVG(Salary) as AvgSalary FROM Employees WHERE IsActive = 1 -- Сначала берем только активных сотрудников GROUP BY DepartmentId HAVING AVG(Salary) > 80000; -- Затем фильтруем результаты агрегации
Главное правило
- Используйте
WHEREдля условий, основанных на данных отдельных строк (например,Salary > 50000,Name LIKE 'A%'). - Используйте
HAVINGдля условий, основанных на результатах агрегатных функций (SUM,AVG,COUNT,MIN,MAX) после группировки.
Видео-ответы
▶
▶
▶
▶
▶
▶