Как в SQL отфильтровать записи, где средняя заработная плата больше 50000?

Ответ

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

Пример запроса:

SELECT DepartmentID, AVG(Salary) AS AverageSalary
FROM Employees
GROUP BY DepartmentID
HAVING AVG(Salary) > 50000;

Объяснение:

  1. GROUP BY DepartmentID группирует сотрудников по отделам.
  2. AVG(Salary) вычисляет среднюю зарплату для каждой группы.
  3. HAVING AVG(Salary) > 50000 фильтрует результаты группировки, оставляя только те отделы, где средняя зарплата превышает 50000.

Ключевое отличие HAVING от WHERE:

  • WHERE фильтрует строки перед группировкой.
  • HAVING фильтрует группы после группировки и агрегации.

Ответ 18+ 🔞

Давай разжую, как бабушка котлету, про этот ваш HAVING. Смотри, история простая, но многие в ней путаются, как в трёх соснах, блядь.

Представь, что у тебя таблица с работягами, Employees. И ты такой: "Хочу посмотреть, в каких отделах народ в среднем получает больше 50 тысяч, а то у меня подозрение, ёбать, что в бухгалтерии все золотые унитазы себе поставили".

И вот ты пишешь:

SELECT DepartmentID, AVG(Salary) AS AverageSalary
FROM Employees
GROUP BY DepartmentID

Всё, ты сгруппировал всех по отделам и для каждого вычислил среднюю зарплату. Получилась такая сводная хуйня. И теперь тебе надо отфильтровать ЭТУ УЖЕ СВОДНУЮ ХУЙНЮ. Вот тут-то и выходит на сцену наш герой — HAVING.

SELECT DepartmentID, AVG(Salary) AS AverageSalary
FROM Employees
GROUP BY DepartmentID
HAVING AVG(Salary) > 50000;

Он как вышибала в клубе. Группы (отделы) уже сформированы, средние значения посчитаны. И HAVING такой, смотрит на каждую группу: "Ты, отдел №3, средняя зарплата 48к? Иди нахуй, не прошёл фейс-контроль". А отделу №7, где 75к в среднем, кивает: "Проходи, красава".

А теперь смотри, где все обосрываются. Они пытаются эту проверку в WHERE впихнуть:

-- ТАК НЕ РАБОТАЕТ, НАХУЙ!
SELECT DepartmentID, AVG(Salary) AS AverageSalary
FROM Employees
WHERE AVG(Salary) > 50000  -- БД тебе тут же: "Иди ты нахуй, мудила"
GROUP BY DepartmentID;

Почему? Да потому что WHERE работает с КАЖДОЙ ОТДЕЛЬНОЙ СТРОКОЙ, ДО ТОГО, как ты их в группы собрал. Это как если бы вышибала начинал бы каждого гостя спрашивать: "Слушай, а какая у тебя средняя зарплата по отделу?". Да он нихуя не знает, он только в дверь зашёл! WHERE не видит этих будущих, ещё несуществующих средних значений. Он видит только конкретные цифры в колонке Salary у каждого человека.

Так что запомни раз и навсегда, чтобы не выглядеть конченым идиотом:

  • WHERE — фильтрует строки ДО группировки. ("Отбери всех, кто получает больше 100к").
  • HAVING — фильтрует группы ПОСЛЕ группировки. ("Покажи отделы, где СРЕДНЯЯ зарплата больше 50к").

Всё. Проще пареной репы. Не усложняй, ебать.