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

Ответ

Ключевое отличие — этап выполнения запроса, на котором применяется фильтрация.

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

Простой аналог: WHERE — это фильтр для сырых данных, HAVING — фильтр для сводного отчета.

Практические примеры:

  1. WHERE с агрегацией: Найти среднюю зарплату по отделам, но только среди сотрудников с зарплатой > 5000.

    SELECT department, AVG(salary) as avg_salary
    FROM employees
    WHERE salary > 5000          -- Фильтрация КАЖДОГО сотрудника до группировки
    GROUP BY department;
  2. HAVING с агрегацией: Найти отделы, где средняя зарплата превышает 7000.

    SELECT department, AVG(salary) as avg_salary
    FROM employees
    GROUP BY department
    HAVING AVG(salary) > 7000;   -- Фильтрация по РЕЗУЛЬТАТУ агрегации (avg_salary)
  3. Комбинирование WHERE и HAVING: Найти отделы с более чем 5 сотрудниками, но учитывать только сотрудников, принятых после 2020 года.

    SELECT department, COUNT(*) as emp_count
    FROM employees
    WHERE hire_date > '2020-01-01' -- Сначала отфильтровать по дате
    GROUP BY department
    HAVING COUNT(*) > 5;           -- Затем отфильтровать сгруппированные результаты

Важное правило: В условии HAVING можно использовать агрегатные функции (COUNT, SUM, AVG, MAX, MIN), а в WHERE — нет. Использование WHERE для первичной фильтрации данных обычно значительно повышает производительность запроса, так как сокращает объем данных для последующей группировки.

Ответ 18+ 🔞

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

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

HAVING — это уже когда ты всё намешал, разлил по стаканам и пробуешь. «О, этот коктейль крепковат, выливаю. Этот слишком сладкий, тоже мимо. А вот этот — то, что надо». Ты фильтруешь уже готовый результат, после всех твоих манипуляций.

Короче: WHERE фильтрует строки, HAVING фильтрует группы. Всё, запомнил? Нет? Ну ёпта, смотри примеры.

Пример 1: WHERE (отсекаем шлак на старте) Хотим среднюю зарплату по отделам, но только для тех, кто получает больше пяти штук. Логично же сначала отсеять нищебродов, а потом считать?

SELECT department, AVG(salary) as avg_salary
FROM employees
WHERE salary > 5000          -- Смотри, мы тут каждому чуваку в лицо смотрим: ты больше 5к? Нет? Нахуй отсюда.
GROUP BY department;

Пример 2: HAVING (фильтруем готовый отчёт) А вот хотим найти отделы, где средняя зарплата зашкаливает за 7к. Сначала всех сгруппируем, посчитаем среднее, а потом уже решим, кто крут.

SELECT department, AVG(salary) as avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 7000;   -- Всё, группы готовы. А теперь: средняя меньше 7? Отдел-лузер, нахуй из отчёта.

Пример 3: Комбо (реальная жизнь, блять) Найти отделы, где больше 5 сотрудников, но считать только тех, кого взяли после 2020 года. Сначала отфильтруем старых пенёчков (WHERE), потом сгруппируем, и потом уже отсеем мелкие отделы (HAVING).

SELECT department, COUNT(*) as emp_count
FROM employees
WHERE hire_date > '2020-01-01' -- Шаг 1: Чувак, тебя наняли в каменном веке? Иди нахуй, ты не в счёт.
GROUP BY department
HAVING COUNT(*) > 5;           -- Шаг 2: Всё, сгруппировали. Что, отдел из 3 человек? Манда с ушами, а не отдел. Не интересует.

Главный подвох, из-за которого все путаются: В WHERE НЕЛЬЗЯ использовать агрегатные функции типа COUNT() или AVG(). Ты же не можешь спросить у одной бутылки «какого хуя ты весишь как все бутылки вместе?». Это бред. А в HAVINGМОЖНО и НУЖНО. Ты как раз спрашиваешь у готовой группы: «Эй, группа, ваше среднее значение — пизда рулю? Если да — вы в отчёте».

И да, всегда старайся сначала отсеять лишнее через WHERE. Это как не тащить в бар всю полку, а взять только нужные бутылки. Запрос будет работать быстрее, и терпения ебать ноль тратить не придётся. Всё, вопрос закрыт.