Ответ
Нет, WHERE не работает напрямую с агрегатными функциями (SUM, COUNT, AVG и т.д.). Для фильтрации по агрегатным функциям нужно использовать HAVING после GROUP BY.
Пример:
SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;
Разница:
- WHERE фильтрует строки до группировки
- HAVING фильтрует после группировки и агрегации
Можно использовать оба в одном запросе:
SELECT department, AVG(salary)
FROM employees
WHERE hire_date > '2020-01-01'
GROUP BY department
HAVING AVG(salary) > 50000; Ответ 18+ 🔞
Да ты глянь, какой прикол! В SQL есть такая хитрая жопа с WHERE и HAVING, которая народ в ступор вгоняет постоянно. Слушай сюда, я тебе на пальцах объясню, а то ты, я смотрю, уже волнение ебать чувствую.
Вот представь: у тебя таблица с работягами, employees. Ты хочешь посчитать среднюю зарплату по отделам. Делаешь GROUP BY department и AVG(salary). И тут тебе в голову приходит гениальная мысль: «А дай-ка я оставлю только те отделы, где средняя зарплата больше 50к!» И ты, естественно, пишешь:
SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 50000 -- Вот тут-то тебя и накроет медным тазом!
GROUP BY department;
И бац! Сервер тебе такой: «Э, сабака сука! Нельзя агрегатную функцию в WHERE использовать!» И он прав, блядь. Потому что WHERE работает как фильтр ДО того, как данные сгруппируют и посчитают среднее. Он смотрит на каждую строчку по отдельности и спрашивает: «Ну-ка, покажи мне свою среднюю зарплату, строка номер 1». А у строки номер 1 своей средней зарплаты нет, она же одна! Это же AVG по всем считает. Вот и получается пиздопроебибна.
Так какого хуя делать-то?
А делать надо так. Сначала ты всё сгруппировал и посчитал (GROUP BY). Получились готовые агрегированные результаты по отделам. И вот только после этого ты можешь их отфильтровать. Для этого и придумали HAVING. Это как WHERE, но для сгруппированных данных.
Правильный запрос выглядит так:
SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000; -- Всё, теперь работает! Фильтруем готовые результаты групп.
А можно ли их вместе использовать? Да похуй, конечно можно! Это вообще мощнейшая комбинация.
Допустим, ты хочешь ещё и учесть только тех, кого наняли после 2020 года, а потом уже смотреть на среднюю зарплату по отделам. Вот тебе полный разгон:
SELECT department, AVG(salary)
FROM employees
WHERE hire_date > '2020-01-01' -- Сначала отфильтруем строки: только новенькие.
GROUP BY department -- Потом сгруппируем этих новеньких по отделам.
HAVING AVG(salary) > 50000; -- И наконец отфильтруем сами отделы по средней ЗП.
Кратко и по делу, чтобы в душу мать въелось:
WHERE— фильтрует строчки ДО группировки. Тут агрегатные функции (SUM,AVG) — хуй с горы.HAVING— фильтрует группы ПОСЛЕ группировки. Тут как раз место для агрегатных функций.
Запомни эту разницу, и удивление пиздец у интервьюеров будет, когда ты не облажаешься на этом классическом вопросе.