В чем разница между HAVING и WHERE в SQL?

Ответ

Основное различие между HAVING и WHERE заключается в этапе выполнения запроса, на котором они применяются для фильтрации данных.

  • WHERE — фильтрует строки до группировки (оператор GROUP BY). Он работает с отдельными записями таблицы.
  • HAVING — фильтрует результаты после группировки. Он применяется к агрегированным данным, таким как суммы (SUM), средние значения (AVG) или количества (COUNT).

Примеры:

-- WHERE: выбираем только сотрудников с зарплатой > 50000, а затем группируем
SELECT department, AVG(salary)
FROM employees
WHERE salary > 50000
GROUP BY department;

-- HAVING: сначала группируем по отделам, затем оставляем только те, где средняя зарплата > 70000
SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 70000;

Ключевые отличия:

  1. WHERE не может использовать агрегатные функции (как AVG(salary) в условии), HAVING — может.
  2. Использование WHERE для первичной фильтрации данных обычно эффективнее, так как сокращает объем данных, поступающих на этап группировки.

Ответ 18+ 🔞

Давай разберём эту тему, а то народ путается, как ёперный театр. Представь, что у тебя куча данных — как будто ты на базаре, где овердохуища всякого барахла. Так вот, WHERE и HAVING — это два разных сторожа на этом базаре, и у них абсолютно разные должностные инструкции, чувак.

WHERE — это охранник на входе.
Его задача проста, как три копейки: он смотрит на каждую запись по отдельности и говорит: «Ты — проходи, а ты — нахуй отсюда». Он фильтрует строки ДО того, как ты начнёшь что-то группировать или считать. Работает с голыми данными из таблицы. Если зарплата меньше 50к — мимо, если имя «Федя» — тоже мимо. Всё, что не прошло — даже не попадает в следующий этап. Эффективно, блядь, потому что мусор отсеивается сразу.

HAVING — это бухгалтер, который сидит уже после кассы.
Ты сначала всё сгруппировал, посчитал средние зарплаты по отделам, общие суммы — и вот тогда приходит этот тип. Он смотрит уже на итоги, на агрегированные данные. «Ага, — говорит, — в отделе маркетинга средняя зарплата 30к? Пиздец, да похуй, закрываем лавочку». Он фильтрует результаты ПОСЛЕ группировки. И да, он может использовать агрегатные функции типа SUM(), AVG(), COUNT() в своих условиях, потому что они уже посчитаны. А WHERE на такое не способен — он же на входе, какие нахуй средние, он каждую запись по отдельности щупает.

Примеры, чтобы вообще ни хуя не осталось непонятного:

-- WHERE работает ПЕРЕД группировкой. Сначала выкинем всех, у кого зп меньше 50к.
SELECT department, AVG(salary)
FROM employees
WHERE salary > 50000  -- Охранник на входе: ты с зп 49к? Иди нахуй, даже в подсчёт не попадёшь.
GROUP BY department;

-- HAVING работает ПОСЛЕ группировки. Сначала сгруппируем всех по отделам, посчитаем среднюю, а потом решим, какие отделы нам интересны.
SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 70000;  -- Бухгалтер после кассы: отдел, где средняя 65к? Не, накрылся медным тазом, не выводим.

Итог, чтобы запомнить на всю жизнь:

  1. WHERE = фильтрация строк. Не может использовать SUM, AVG и т.д. Работает ДО GROUP BY.
  2. HAVING = фильтрация групп. Может (и обычно так и делает) использовать агрегатные функции. Работает ПОСЛЕ GROUP BY.
  3. Важнейший лайфхак: всегда старайся сначала отфильтровать лишнее через WHERE. Зачем тащить на группировку и агрегацию тонну ненужных данных? Это как везти весь базар на склад, чтобы потом выкинуть половину. Гораздо эффективнее отсеять мусор на входе.