Ответ
Ключевое отличие — этап выполнения запроса, на котором применяется фильтрация.
WHEREфильтрует отдельные строки таблицы ДО выполнения операций группировки (GROUP BY) или агрегации.HAVINGфильтрует уже сгруппированные результаты (агрегаты) ПОСЛЕ выполненияGROUP BY.
Сравнительная таблица:
| WHERE | HAVING | |
|---|---|---|
| Применяется к | Отдельным записям (строкам). | Группам записей, созданным GROUP BY. |
| Используется с | Любыми столбцами таблицы. | Только с агрегатными функциями (SUM, AVG, COUNT, MIN, MAX) или столбцами из GROUP BY. |
| Порядок в запросе | Выполняется до GROUP BY. |
Выполняется после GROUP BY. |
Примеры:
-
WHERE(фильтрация строк перед группировкой):-- Найти среднюю зарплату по отделам, но только для сотрудников с зарплатой > 50000 SELECT department, AVG(salary) as avg_salary FROM employees WHERE salary > 50000 -- Фильтр применяется к каждой строке ДО группировки GROUP BY department; -
HAVING(фильтрация групп после группировки):-- Найти отделы, где средняя зарплата превышает 70000 SELECT department, AVG(salary) as avg_salary FROM employees GROUP BY department HAVING AVG(salary) > 70000; -- Фильтр применяется к результату агрегации ПОСЛЕ группировки -
Комбинирование
WHEREиHAVING:-- Найти отделы (исключая 'HR'), где средняя зарплата менеджеров (job_title = 'Manager') превышает 80000 SELECT department, AVG(salary) as avg_salary FROM employees WHERE job_title = 'Manager' -- Сначала отфильтровать строки AND department != 'HR' GROUP BY department HAVING AVG(salary) > 80000; -- Затем отфильтровать сгруппированные результаты
Важно: Использовать HAVING без GROUP BY технически возможно, но это эквивалентно WHERE для агрегатных функций по всему набору данных и обычно является признаком плохого дизайна запроса.
Ответ 18+ 🔞
А, слушай, вот эта тема про WHERE и HAVING — это классика, на которой половина джунов, блядь, мозги сломает, а потом охуевает, когда понимает. Ёпта, сейчас разжуем.
Представь себе, что ты — царь и бог своей таблицы employees. И вот ты решил посчитать, кто сколько получает.
WHERE — это как твой личный охранник на входе в клуб.
Он смотрит на каждого отдельного человека (строку) и говорит: «Ты, с зарплатой меньше 50к, — нахуй отсюда, в пизду. Ты, из отдела «Хуй пойми кто», — тоже вали».
То есть, фильтрация происходит ДО того, как ты вообще начал что-то считать или группировать. Ты просто отсеиваешь мусор.
-- Давай среднюю зарплату по отделам, но только для тех, кто получает больше 50к
SELECT department, AVG(salary) as avg_salary
FROM employees
WHERE salary > 50000 -- Вот этот охранник! Каждую строку проверяет.
GROUP BY department;
Видишь? Сначала выгнали всех нищебродов, а потом уже по оставшимся крутым пацанам среднюю зарплату считаем.
А теперь HAVING — это бухгалтер, который сидит уже после того, как все посчитано.
Ты уже сгруппировал всех по отделам, получил средние зарплаты. И вот этот бухгалтер смотрит на итоговые цифры по группам и говорит: «Отдел «Маркетинг»? Средняя 65к? Мало, блядь. Нахуй такой отдел из отчета. А вот «IT» с его 150к — о, годится».
-- Найти отделы, где средняя зарплата зашкаливает за 70к
SELECT department, AVG(salary) as avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 70000; -- Вот этот бухгалтер! Работает с готовыми группами.
А теперь, внимание, ебушки-воробушки, главный парадокс для тех, кто в танке:
В WHERE ты НЕ МОЖЕШЬ использовать агрегатные функции типа AVG(salary). Потому что охранник на входе не знает, какая там в среднем по палате! Он видит только конкретного человека.
А в HAVING — МОЖЕШЬ и ДОЛЖЕН. Потому что бухгалтер работает именно с итогами.
Их, сука, можно и нужно комбинировать, как хороший коктейль:
-- Давай найдем отделы (кроме сраного 'HR'), где средняя зарплата у 'Manager' за 80к бьет
SELECT department, AVG(salary) as avg_salary
FROM employees
WHERE job_title = 'Manager' -- Охранник: пускаем только менеджеров
AND department != 'HR' -- И HR-ов нахуй
GROUP BY department
HAVING AVG(salary) > 80000; -- Бухгалтер: а теперь покажи только те отделы, где средняя огонь
И последнее, на что подписываюсь кровью: использовать HAVING без GROUP BY — это как прийти в ресторан и заказать «соус отдельно». Технически можно, но все на тебя смотреть будут как на еблана. Это признак того, что запрос писал человек, у которого в голове — ветер, блядь, и мусор. Не делай так.
Короче, запомни:
WHERE = фильтруем строки ДО группировки.
HAVING = фильтруем группы ПОСЛЕ группировки.
Всё. Разобрались. Чих-пых тебя в сраку, если забудешь.