Оператор SQL HAVING
Оператор SQL HAVING является указателем на результат выполнения агрегатных функций. Агрегатной функцией в языке SQL называется функция, возвращающая какое-либо одно значение по набору значений столбца. Такими функциями являются: SQL COUNT(), SQL MIN(), SQL MAX(), SQL AVG(), SQL SUM().
Оператор SQL HAVING имеет следующий синтаксис:
HAVING aggregate_function(column_name) operator value
Оператор SQL HAVING аналогичен оператору SQL WHERE за тем исключением, что применяется не для всего набора столбцов таблицы, а для набора созданного оператором SQL GROUP BY и применяется всегда строго после него.
Примеры оператора SQL HAVING. Имеется следующая таблица Artists:
| Singer | Album | Year | Sale |
| The Prodigy | Invaders Must Die | 2008 | 1200000 |
| Drowning Pool | Sinner | 2001 | 400000 |
| Massive Attack | Mezzanine | 1998 | 2300000 |
| The Prodigy | Fat of the Land | 1997 | 600000 |
| The Prodigy | Music For The Jilted Generation | 1994 | 1500000 |
| Massive Attack | 100th Window | 2003 | 1200000 |
| Drowning Pool | Full Circle | 2007 | 800000 |
| Massive Attack | Danny The Dog | 2004 | 1900000 |
| Drowning Pool | Resilience | 2013 | 500000 |
Пример 1. Используя оператор SQL HAVING вывести название исполнителей (Singer) число продаж альбомов (Sale) которого больше 2000000:
SELECT Singer, SUM(Sale) FROM Artists GROUP BY Singer HAVING SUM(Sale) > 2000000
| Singer | Sum(Sale) |
| Massive Attack | 54000000 |
| The Prodigy | 33000000 |
В результат не попала группа Drowning Pool, так как общее число проданных ею пластинок равняется 1700000
Пример 2. Используя оператор SQL HAVING вывести название исполнителя, который исполнялся еще до 1995 года:
SELECT Singer, MIN(Year) FROM Artists GROUP BY Singer HAVING MIN(Year) < 1995
| Singer | MIN(Year) |
| The Prodigy | 1994 |
SQL оператор HAVING
В этом учебном материале вы узнаете, как использовать SQL оператор HAVING с синтаксисом и примерами.
Описание
SQL оператор HAVING используется в сочетании с оператором GROUP BY, чтобы ограничить группы возвращаемых строк только теми, чьё условие TRUE.
Синтаксис
Синтаксис оператора HAVING в SQL:
SELECT expression1, expression2, . expression_n,
aggregate_function (aggregate_expression)
FROM tables
[WHERE conditions]
GROUP BY expression1, expression2, . expression_n
HAVING condition;
Параметры или аргументы
expression1 , expression2 , . expression_n Выражения, которые не заключены в агрегатную функцию должны быть включены в предложение GROUP BY в конце SQL оператора. aggregate_function Это агрегатная функция, такая как SUM, COUNT, MIN, MAX или AVG. aggregate_expression Это столбец или выражение, для которого будет использоваться aggregate_function . tables Таблицы, из которых вы хотите получить записи. В предложении FROM должна быть указана хотя бы одна таблица. WHERE conditions Необязательный. Это условия для выбора записей. HAVING condition Это еще одно условие, применяемое только к агрегированным результатам, чтобы ограничить группы возвращаемых строк. Только те группы, состояние которых оценивается как true, будут включены в набор результатов.
Пример - использование функции SUM
Давайте рассмотрим SQL пример HAVING, в котором используется SQL функция SUM.
Вы также можете использовать SQL функцию SUM для возврата названия department и total sales (общих продаж в связанном отделе). SQL-предложение HAVING отфильтрует результаты так, что будут возвращены только department с продажами более 1000 $.
Что такое having в sql
Мы уже рассматривали запрос получения средней стоимости аренды жилых помещений в зависимости от типа жилья:
MySQLSELECT home_type, AVG(price) as avg_price FROM Rooms GROUP BY home_type
home_type avg_price Private room 89.4286 Entire home/apt 148.6667 Shared room 40 Давайте доработаем этот запрос таким образом, чтобы в итоговой выборке отображались только те группы, чья средняя стоимость больше 50.
Обладая предыдущим опытом, есть большой соблазн попытаться использовать для этих целей оператор WHERE . Но при попытке выполнить такой запрос СУБД неминуемо выдаст ошибку, указав что мы некорректно используем синтаксис WHERE avg_price > 50 .
MySQLSELECT home_type, AVG(price) as avg_price FROM Rooms GROUP BY home_type WHERE avg_price > 50Говоря наперёд, для фильтрации групп мы должны использовать оператор HAVING :
MySQLSELECT home_type, AVG(price) as avg_price FROM Rooms GROUP BY home_type HAVING avg_price > 50
home_type avg_price Private room 89.4286 Entire home/apt 148.6667 Но почему же мы не могли использовать WHERE и зачем нужен отдельный оператор для этой цели? Все дело в порядке выполнения SQL запроса.
Наш первый запрос был неверный, потому что мы пытались использовать поле avg_price у образовавшихся групп ещё до их образования, так как выполнение оператора WHERE предшествует группировке.
То есть оператор WHERE в момент его исполнения ничего не знает о последующей группировке, он работает только с записями из таблицы. Так мы, например, с его помощью можем отфильтровать записи таблицы Rooms по цене до применения группировки и лишь затем вычислить среднюю стоимость групп оставшегося жилья:
MySQLSELECT home_type, AVG(price) as avg_price FROM Rooms WHERE price > 50 GROUP BY home_type
home_type avg_price Private room 96.875 Entire home/apt 148.6667 MySQLSELECT [константы, агрегатные_функции, поля_группировки] FROM имя_таблицы WHERE условия_на_ограничения_строк GROUP BY поля_группировки HAVING условие_на_ограничение_строк_после_группировки ORDER BY условие_сортировкиДля примера давайте получим минимальную стоимость каждого типа жилья c телевизором. При этом нас интересуют только типы жилья, содержащие как минимум 5 жилых помещений, относящихся к ним.
Чтобы получить такой результат мы должны:
Сначала получить все данные из таблицы
MySQLSELECT ... FROM Rooms;MySQLSELECT ... FROM Rooms WHERE has_tv = TrueMySQLSELECT ... FROM Rooms WHERE has_tv = True GROUP BY home_typeMySQLSELECT ... FROM Rooms WHERE has_tv = True GROUP BY home_type HAVING COUNT(*) >= 5MySQLSELECT home_type, MIN(price) as min_price FROM Rooms WHERE has_tv = True GROUP BY home_type HAVING COUNT(*) >= 5;Предложение HAVING
Если предложение WHERE определяет предикат для фильтрации строк, то предложение HAVING применяется после группировки для определения аналогичного предиката, фильтрующего группы по значениям агрегатных функций. Это предложение необходимо для проверки значений, которые получены с помощью агрегатной функции не из отдельных строк источника записей, определенного в предложении FROM , а из групп таких строк. Поэтому такая проверка не может содержаться в предложении WHERE .
Получить количество ПК и среднюю цену для каждой модели, средняя цена которой менее $800
Консоль
![]()
Выполнить
В результате выполнения запроса получим:
Заметим, что в предложении HAVING нельзя использовать псевдоним (Avg_price), используемый для именования значений агрегатной функции в предложении SELECT . Дело в том, что предложение SELECT , формирующее выходной набор запроса, выполняется предпоследним перед предложением ORDER BY . Ниже приведен порядок обработки предложений в операторе SELECT :
Этот порядок не соответствует синтаксическому порядку общего представления оператора SELECT , который ближе к естественному языку:
Следует отметить, что предложение HAVING может использоваться и без предложения GROUP BY. При отсутствии предложения GROUP BY агрегатные функции применяются ко всему выходному набору строк запроса, т.е. в результате мы получим всего одну строку, если выходной набор не пуст.
Таким образом, если условие на агрегатные значения в предложение HAVING будет истинным, то эта строка будет выводиться, в противном случае мы не получим ни одной строки. Рассмотрим такой пример.
Найти максимальную, минимальную и среднюю цену на персональные компьютеры.
Решение этой задачи дает следующий запрос:
Консоль
![]()
Выполнить
Предыдущая запись


Консоль