Основное различие между HAVING
и WHERE
заключается в времени применения условия и типе данных, к которым они могут обращаться. Рассмотрим детально:
SELECT Department, AVG(Salary) as AvgSalary
FROM Employees
WHERE HireDate > '2020-01-01' -- Фильтрация ДО группировки
GROUP BY Department
HAVING AVG(Salary) > 50000 -- Фильтрация ПОСЛЕ группировки
WHERE:
HAVING:
-- НЕВЕРНО (вызовет ошибку):
SELECT Department, AVG(Salary)
FROM Employees
WHERE AVG(Salary) > 50000 -- WHERE не может использовать агрегатные функции
GROUP BY Department
-- ВЕРНО:
SELECT Department, AVG(Salary)
FROM Employees
GROUP BY Department
HAVING AVG(Salary) > 50000 -- HAVING работает с результатами агрегации
WHERE обычно более эффективен, так как:
HAVING работает с уже сгруппированными данными:
-- Средняя зарплата по отделам среди сотрудников, принятых после 2020 года,
-- где средняя зарплата отдела больше 50000
SELECT Department, AVG(Salary) as AvgSalary
FROM Employees
WHERE HireDate > '2020-01-01' -- Фильтр строк ДО группировки
GROUP BY Department
HAVING AVG(Salary) > 50000 -- Фильтр групп ПОСЛЕ группировки
-- Все сотрудники с зарплатой больше 50000
SELECT *
FROM Employees
WHERE Salary > 50000 -- Простая фильтрация без группировки
-- Отделы с более чем 5 сотрудниками
SELECT Department, COUNT(*) as EmpCount
FROM Employees
GROUP BY Department
HAVING COUNT(*) > 5 -- Фильтрация по результату агрегации
С GROUP BY но без HAVING:
-- Просто группировка без фильтрации результатов
SELECT Department, AVG(Salary)
FROM Employees
GROUP BY Department
HAVING без GROUP BY (агрегация по всей таблице):
-- Проверка общей средней зарплаты
SELECT AVG(Salary)
FROM Employees
HAVING AVG(Salary) > 50000
Использование алиасов:
-- HAVING может использовать алиасы из SELECT
SELECT Department, AVG(Salary) as AvgSal
FROM Employees
GROUP BY Department
HAVING AvgSal > 50000 -- Работает с алиасом
Резюмируем: WHERE
фильтрует строки перед группировкой и не может использовать агрегатные функции, тогда как HAVING
фильтрует результаты после группировки и работает с агрегированными данными. Оптимальная практика — фильтровать как можно больше данных с помощью WHERE
до группировки, а HAVING
использовать только для фильтрации итоговых агрегированных результатов.