Ответ
Да, можно, но это имеет специфическое применение и зависит от СУБД.
Техническая суть:
- Без
GROUP BYвесь набор результатов запроса трактуется как одна агрегированная группа. - Предложение
HAVINGв этом случае фильтрует результат по агрегатным функциям, применённым ко всей таблице.
Пример (стандартный SQL):
SELECT COUNT(*) AS total_employees, AVG(salary) AS avg_salary
FROM employees
HAVING COUNT(*) > 100 AND AVG(salary) < 50000;
Этот запрос вернёт одну строку с общим числом сотрудников и средней зарплатой, но только если оба условия выполняются для всей таблицы.
Важные нюансы:
- Без агрегатных функций использование
HAVINGбессмысленно — для фильтрации неагрегированных строк всегда используйтеWHERE. - Поддержка СУБД: Стандарт SQL требует
GROUP BYдляHAVING. Однако многие СУБД (MySQL, PostgreSQL) допускают такой синтаксис. В SQL Server это вызовет ошибку. - Практическое применение: Основной сценарий — фильтрация результатов агрегации по всей таблице, когда группировка не требуется. Например, проверка глобальных метрик перед выполнением дальнейших действий в скрипте.
Лучшая практика: Для ясности кода, даже если ваша СУБД разрешает HAVING без GROUP BY, рассмотрите использование вложенного запроса:
SELECT * FROM (
SELECT COUNT(*) AS cnt FROM employees
) AS subquery
WHERE cnt > 100; Ответ 18+ 🔞
Да, конечно можно, но это как пытаться надеть носки на уши — технически возможно, но выглядит дико и смысл теряется. СУБД, конечно, не лыком шита, и многие такое проглотят, но надо понимать, что ты делаешь.
Если по-простому:
Когда ты пишешь HAVING без GROUP BY, база данных смотрит на всю твою таблицу как на одну большую, жирную группу. Всё, что ты вытащил — это один монолитный кусок. И HAVING в этом случае фильтрует результат по каким-то глобальным, суммарным показателям.
Вот, смотри пример, чтобы было понятно:
SELECT COUNT(*) AS total_employees, AVG(salary) AS avg_salary
FROM employees
HAVING COUNT(*) > 100 AND AVG(salary) < 50000;
Что здесь происходит? Запрос говорит: «Дай мне общее число работников и среднюю зарплату по всей конторе. Но верни результат только если этих работников больше сотни и средняя зарплата у них меньше пятидесяти тысяч». То есть, если в компании сидят сто пятьдесят человек, но все получают по семьдесят, то на выходе будет пусто — ни одной строки. Всё честно.
А теперь важные детали, на которых можно обжечься:
-
Без агрегатных функций — нихуя не выйдет. Если в
SELECTу тебя нетCOUNT(),SUM(),AVG()и прочей агрегатной братии, тоHAVINGтут — как пятое колесо у телеги. Для фильтрации обычных строк есть жеWHERE, зачем выёбываться? -
Не все СУБД такие всепрощающие. Стандарт SQL, эта старая зануда, требует
GROUP BYдляHAVING. Но такие либеральные системы, как MySQL или PostgreSQL, махнут рукой и пропустят. А вот SQL Server — тот ещё принципиальный тип — сразу начнёт орать ошибкой. Так что смотри, где пишешь. -
Зачем это вообще нужно? Ну, например, ты пишешь скрипт, которому нужно проверить: «А вообще в таблице больше ста записей? А среднее значение не зашкаливает?». Если условия не проходят — дальше скрипт даже не продолжает. Удобно.
Но если хочешь, чтобы код был понятным даже тому мудаку, который будет его читать через полгода (возможно, тебе самому), лучше сделай по-человечески:
SELECT * FROM (
SELECT COUNT(*) AS cnt FROM employees
) AS subquery
WHERE cnt > 100;
Вложенный запрос, всё прозрачно. Никаких вопросов, никакой магии. И СУБД не сломается, и коллеги тебя проклянут меньше.