Mysql having примеры. HAVING SQL: описание, синтаксис, примеры

Предложение HAVING используется в комбинации с предложением GROUP BY. Оно может быть использовано в операторе SELECT для фильтрации записей возвращемых предложением GROUP BY.

Синтаксис предложения HAVING

aggregate_function может быть функцией подобной SUM, COUNT, MIN, или MAX.

Пример использования функции SUM
Например, вы можете использовать функцию SUM для поиска названия отдела и суммы продаж (для соответствующих отделов). Предложение HAVING может выбрать только те отделы продажи которых больше $1000.

SELECT department, SUM(sales) AS "Total sales" FROM order_details GROUP BY department HAVING SUM(sales) > 1000 ;

Пример использования функции COUNT
Например, вы можете использовать функцию COUNT для выборки имени отдела и количество сотрудников (в соответствующем отделе) которые заработали более $25000 в год. Предложение HAVING отберет только те отделы, где таких работников более 10.

Пример использования функции MIN
Например, вы можете использовать функцию MIN для возврата названия отдела и минимальный доход этого отдела. Предложение HAVING вернет только те отделы у которых размер выручки начинается с $35000.

SELECT department, MIN(salary) AS "Lowest salary" FROM employees GROUP BY department HAVING MIN(salary) = 35000 ;

Пример использования функции MAX
Например, вы также можете использовать функцию для выборки имени отдела и максимальногй выручки отдела. Предложение HAVING вернет только те отделы, чей максимальный доход менее $50000.

SELECT department, MAX(salary) AS "Highest salary" FROM employees GROUP BY department HAVING MAX(salary) < 50000 ;

В предыдущей статье мы разобрали . Там я написал, что данная конструкция позволяет выбирать отдельные группы и для каждой группы вычислять функции, указанные после SELECT . А HAVING позволяет, согласно результату выполнения функций, отфильтровать лишние строки из групп. Разберём это подробнее.

Вспомним нашу предыдущую задачу, где мы вычисляли среднюю цену на молоко для конкретной сети супермаркетов. Давайте с Вами не просто посмотрим среднюю цену, но и при этом выведем только те сети супермаркетов, где средняя цена ниже 38 .

Для этой фильтрации по результатам выполнения агрегатной функции используется в SQL команда HAVING :

SELECT `shop_id`, AVG(`price`) FROM `table` GROUP BY `shop_id` HAVING AVG(`price`) < 38

В результате, вместо 4-х строк у нас будет лишь 3 :

shop_id AVG(`price`)
1 37.5
2 36.0
3 37.0

Если конструкции GROUP BY не будет, то HAVING будет применяться не к конкретной группе, а ко всей выборке. Это означает, что если условие HAVING будет выполняться, то оно никакого влияния не окажет. А если выполняться не будет, то не будет ни одной результирующей строки.

Наконец, последним при вычислении табличного выражения используется раздел HAVING (если он присутствует).

Раздел HAVING может осмысленно появиться в табличном выражении только в том случае, когда в нем присутствует раздел GROUP BY . Условие поиска этого раздела задает условие на группу строк сгруппированной таблицы. Формально раздел HAVING может присутствовать и в табличном выражении, не содержащем GROUP BY. В этом случае полагается, что результат вычисления предыдущих разделов представляет собой сгруппированную таблицу, состоящую из одной группы без выделенных столбцов группирования.

Условие поиска раздела HAVING строится по тем же синтаксическим правилам, что и условие поиска раздела WHERE, и может включать те же самые предикаты. Однако имеются специальные синтаксические ограничения по части использования в условии поиска спецификаций столбцов таблиц из раздела FROM данного табличного выражения. Эти ограничения следуют из того, что условие поиска раздела HAVING задает условие на целую группу, а не на индивидуальные строки.

Поэтому в арифметических выражениях предикатов, входящих в условие выборки раздела HAVING , прямо можно использовать только спецификации столбцов, указанных в качестве столбцов группирования в разделе GROUP BY . Остальные столбцы можно специфицировать только внутри спецификаций агрегатных функций COUNT, SUM, AVG, MIN и MAX , вычисляющих в данном случае некоторое агрегатное значение для всей группы строк. Аналогично обстоит дело с подзапросами, входящими в предикаты условия выборки раздела HAVING : если в подзапросе используется характеристика текущей группы, то она может задаваться только путем ссылки на столбцы группирования.

Результатом выполнения раздела HAVING является сгруппированная таблица, содержащая только те группы строк, для которых результат вычисления условия поиска есть TRUE. В частности, если раздел HAVING присутствует в табличном выражении, не содержащем GROUP BY , то результатом его выполнения будет либо пустая таблица, либо результат выполнения предыдущих разделов табличного выражения, рассматриваемый как одна группа без столбцов группирования.

HAVING COUNT

Выбрать коды товаров, покупаемых более чем одним покупателем:

SELECT stock FROM ordsale GROUP BY stock HAVING COUNT (*) > 1;

HAVING MIN

Получить значения минимального и максимального оклада для клерков каждого отдела, где самое низкое жалованье составляет менее $1,000:

SELECT deptno, MIN (sal), MAX (sal) FROM emp WHERE job = ‘CLERK’ GROUP BY deptno HAVING MIN (sal)

Пример 2. База данных и таблица - те же, что и в примере 1.

Используя операторы SQL HAVING и GROUP BY, требуется вывести категории, в какой-либо части которых минимальное количество поданных объявлений не превышает 100. Для этого пишем следующий запрос:

SELECT Category, Units, MIN (Units) AS Minimum FROM Ads GROUP BY Category HAVING MIN (Units)

Пример 3. База данных и таблица - те же, что и в предыдущих примерах.

Используя операторы SQL HAVING и GROUP BY, требуется вывести категории объявлений, в которых более двух частей. Пишем следующий запрос:

SELECT Category, Part FROM Ads GROUP BY Category HAVING COUNT (*)>2

Результатом будет следующая таблица:

Category Part
Досуг Книги
Досуг Музыка
Досуг Игры
Недвижимость Квартиры
Недвижимость Дачи
Недвижимость Дома

Самостоятельно поработайте с таблицей Staff (штатные сотрудники) базы данных фирмы. В ней есть столбцы Name (фамилия), Dept (номер отдела), Years (длительность трудового стажа) и Salary (размер заработной платы). Примеры для самостоятельного решения со ссылками для проверки решения - после таблицы.

Name Dept Years Salary
Sanders 20 7 18357.5
Junkers 15 6 16232.8
Moonlight 15 8 21500.6
Pernal 20 8 18171.2
Aisen 15 7 19540.7
McGregor 15 7 15790.8
Marenghi 38 5 17506.8
Doctor 20 5 12322.4
Factor 38 8 16228.7

Пример 5. Определить номера отделов, в которых средний трудовой стаж сотрудников больше 6.5 лет.

Оператор SQL HAVING и сравнение со значением, возвращаемым квантором ALL или ANY (SOME)

Оператор SQL HAVING можно использовать для выборки данных, соответствующим результатам сравнения не только с заданным числом, но и со значением, возвращаемым квантором ALL или ANY (SOME). Квантор ALL возвращает из запроса, к которому он применяется, максимальное значение и тогда при помощи оператора HAVING происходит сравнение с максимальным значением. Например, ALL(10, 15, 20) вернёт 20. Квантор ANY (и его аналог SOME) возвращает минимальное значение и тогда при помощи оператора HAVING происходит сравнение с минимальным значением. Синтаксис запроса с оператором SQL HAVING, определяющий сравнение со значением, возвращаемым квантором ALL или ANY (SOME) выглядит следующим образом:.

SELECT ИМЕНА_СТОЛБЦОВ FROM ИМЯ_ТАБЛИЦЫ GROUP BY ИМЯ_СТОЛБЦА HAVING АГРЕГАТНАЯ_ФУНКЦИЯ (ИМЯ СТОЛБЦА) ОПЕРАТОР_СРАВНЕНИЯ КВАНТОР (SELECT АГРЕГАТНАЯ_ФУНКЦИЯ (ИМЯ СТОЛБЦА) FROM ИМЯ_ТАБЛИЦЫ GROUP BY ИМЯ_СТОЛБЦА)

Пример 7. Есть база данных "Театр". В ней есть таблица Play, содержащая данные о постановках в театре. В этой таблице есть поля PlayID (идентификатор), Name (название), Genre (жанр), Author (автор), Dir_ID (внешний ключ - идентификатор режиссёра), PremiereDate (дата премьеры), LastDate (дата окончания). Требуется определить самый популярный жанр театра, то есть жанр, в котором поставлено наибольшее количество постановок.

Используя операторы SQL HAVING и GROUP BY, пишем первую часть запроса к таблице Play, которая задаёт сравнение числа строк, сгруппированных по жанру:

SELECT Genre FROM Play GROUP BY Genre HAVING COUNT (*) >=

Теперь нужно определить, с чем сравнивать. Это максимальное число записей в той же таблице, сгруппированных по жанру. Поэтом нам понадобиться квантор ALL. Пишем вторую часть запроса:

ALL (SELECT COUNT (*) FROM PLAY GROUP BY Genre)

Весь запрос для определения самого популярного жанра в театре будет следующим:

SELECT Genre FROM Play GROUP BY Genre HAVING COUNT (*) >= ALL (SELECT COUNT (*) FROM PLAY GROUP BY Genre)

Оператор SQL HAVING в соединениях таблиц

Вернёмся к запросам с оператором SQL HAVING, в которых сравнение проводится с заданным числом, как в первом параграфе. Но усложним задачу. На практике часто число строк в результате запроса определяется внешним ключом, ссылающимся на другую таблицу..

Пример 8. Продолжаем работать с базой данных "Театр". Нам понадобятся таблицы Play, содержащая данные о постановках в театре и Team, содержащая данные о ролях актёров. Требуется вывести список моноспектаклей (спектаклей с одним актёром). Ниже приведена схема базы данных "Театр" (для увеличения рисунка нажать на него левой кнопкой мыши).

Если ещё точнее, нам нужно выбрать спектакли, в которых лишь одна роль. Среди полей в таблице Team есть PlayID - внешний ключ, ссылающийся на таблицу Play. В каждой записи таблицы Team этот внешний ключ определяет постановку, в которой исполняется данная роль. Если мы соединим таблицы Play и Team по ключу PlayID, то мы сможем определить количество ролей в постановках. Так как мы соединяем две таблицы, а не больше, то для простоты можем использовать соединение без оператора JOIN, перечисляя таблицы через запятую, а для обозначения условия соединения используя слово WHERE.

C оператором HAVING используем агрегатную функцию COUNT - для подсчёта числа ролей в каждой постановке. Весь запрос для определения спектаклей с одной ролью, а следовательно, с одним актёром будет следующим:

Написать запросы с оператором SQL HAVING самостоятельно, а затем посмотреть решения

Пример 9. Продолжаем работать с базой данных "Театр". Вывести список актеров, которые в одном спектакле играют более одной роли, и количество их ролей.

Использовать оператор JOIN. Естественно, использовать HAVING, GROUP BY.

Реляционные базы данных и язык SQL

Он имеет в своем арсенале множество мощных инструментов манипулирования данными, хранящихся в виде таблиц.

Несомненно, возможность группировать данные при их выборке по определенному признаку является одним из таких инструментов. HAVING наряду с оператором WHERE позволяет определять условия выборки уже сгруппированных некоторым образом данных.

Параметр HAVING SQL: описание

Прежде всего стоит отметить, что данный параметр является необязательным и применяется исключительно в связке с параметром GROUP BY. Как вы помните, GROUP BY применяется тогда, когда в SELECT используются агрегатные функции, и результаты их вычислений нужно получить по определенным группам. Если WHERE позволяет задать условия выборки перед тем, как данные будут сгруппированы, то HAVING содержит условия, касающиеся данных уже непосредственно в самих группах. Для лучшего понимания давайте разберем пример со схемой, представленный на рисунке ниже.

Это отличный пример, дающий HAVING SQL описание. Дана таблица с перечнем наименований продукции, компаниями, выпускающими их, и некоторыми другими полями. В запросе в верхнем правом углу мы пытаемся получить информацию о том, какое количество наименований продукции выпускает каждая компания, при этом в результат мы хотим вывести только те компании, которые выпускают более 2 наименований. Параметр GROUP BY сформировал три группы, соответствующие названиям компаний, для каждой из которых посчитано количество продукции (строк). Но параметр HAVING своим условием отсек одну группу из результирующей выборки, поскольку она не удовлетворяла условию. В результате мы получаем две группы, соответствующие компаниям с количеством продукции 5 и 3.

Может возникнуть вопрос о том, зачем использовать HAVING, если в SQL имеется WHERE. Если бы мы использовали WHERE, то он бы смотрел на общее количество строк в таблице, а не по группам, и условие не имело бы смысла в данном случае. Однако довольно часто они прекрасно уживаются в одном запросе.

На примере выше мы можем видеть, как сначала происходит отбор данных по именам работников, указанным в параметре WHERE, а затем сгруппированный в GROUP BY результат проходит дополнительную проверку по сумме зарплаты для каждого работника.

Параметр SQL HAVING: примеры, синтаксис

Рассмотрим некоторые особенности синтаксиса HAVING SQL. Описание данного параметра довольно простое. Во-первых, как уже отмечалось, он используется исключительно в связке с параметром GROUP BY и указывается сразу же после него и перед ORDER BY, если таковой имеется в запросе. Оно и понятно, так как HAVING определяет условия для уже сгруппированных данных. Во-вторых, в условии этого параметра можно использовать только агрегатные функции и поля, указанные в параметре GROUP BY. Все условия в данном параметре указываются точно таким же образом, как и в случае с WHERE.

Заключение

Как видите, ничего сложного в данном операторе нет. Семантически он используется так же, как и WHERE. Важно понять то, что WHERE используют относительно всех выбираемых данных, а HAVING - только по отношению к группам, определенным в параметре GROUP BY. Мы представили исчерпывающее для HAVING SQL описание, которого достаточно для уверенной работы с ним.



Похожие статьи