HAVING SQL: описание, синтаксис, примеры. Команда SELECT Раздел HAVING Sql group by having как работает

В предыдущей статье мы разобрали . Там я написал, что данная конструкция позволяет выбирать отдельные группы и для каждой группы вычислять функции, указанные после 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)

Предложение 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 ;