SQL предложения HAVING
w3big.comLatest web development tutorials
Предыдущий: SQL GROUP BY заявление
Функция SQL UCASE (): Следующий
предложения HAVING
Увеличение SQL предложения HAVING, потому что, WHERE ключевое слово нельзя использовать с агрегатными функциями.
Предложения HAVING позволяет фильтровать после каждого набора пакетов данных.
SQL HAVING Синтаксис
SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value;
Демонстрационная база данных
В этом уроке мы будем использовать w3big образец базы данных.
Ниже приводится выбранные «сайты» таблица данных:
+----+--------------+---------------------------+-------+---------+ | id | name | url | alexa | country | +----+--------------+---------------------------+-------+---------+ | 1 | Google | https://www. google.cm/ | 1 | USA | | 2 | 淘宝 | https://www.taobao.com/ | 13 | CN | | 3 | 本教程 | http://www.w3big.com/ | 4689 | CN | | 4 | 微博 | http://weibo.com/ | 20 | CN | | 5 | Facebook | https://www.facebook.com/ | 3 | USA | | 7 | stackoverflow | http://stackoverflow.com/ | 0 | IND | +----+---------------+---------------------------+-------+---------+
Вот данные «access_log» веб-сайт записи доступа к таблице:
mysql> SELECT * FROM access_log; +-----+---------+-------+------------+ | aid | site_id | count | date | +-----+---------+-------+------------+ | 1 | 1 | 45 | 2016-05-10 | | 2 | 3 | 100 | 2016-05-13 | | 3 | 1 | 230 | 2016-05-14 | | 4 | 2 | 10 | 2016-05-14 | | 5 | 5 | 205 | 2016-05-14 | | 6 | 4 | 13 | 2016-05-15 | | 7 | 3 | 220 | 2016-05-15 | | 8 | 5 | 545 | 2016-05-16 | | 9 | 3 | 201 | 2016-05-17 | +-----+---------+-------+------------+ 9 rows in set (0. 00 sec)
Примеры SQL HAVING
Теперь мы хотим, чтобы найти общее число посещений больше, чем 200 сайтов.
Мы используем следующую инструкцию SQL:
примеров
SELECT Websites.name, Websites.url, SUM(access_log.count) AS nums FROM (access_logINNER JOIN Websites
ON access_log.site_id=Websites.id)
GROUP BY Websites.name
HAVING SUM(access_log.count) > 200;
Выполнить выше SQL вывода результатов заключаются в следующем:
Теперь мы хотим, чтобы найти общее число посещений больше, чем 200 сайтов, и менее чем 200 тИЦ.
Добавим обычный оператор SQL предложения WHERE:
примеров
SELECT Websites.name, SUM(access_log.count) AS nums FROM
Websites
INNER JOIN access_log
ON Websites.id=access_log.site_id
WHERE Websites.alexa GROUP BY Websites.name
HAVING
SUM(access_log.count) > 200;
Выполнить выше SQL вывода результатов заключаются в следующем:
Предыдущий: SQL GROUP BY заявление
Функция SQL UCASE (): Следующий
w3big.
Оператор HAVING
Мы уже рассматривали запрос получения средней стоимости аренды жилых помещений в зависимости от типа жилья:
SELECT 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.
SELECT home_type, AVG(price) as avg_price FROM Rooms GROUP BY home_type WHERE avg_price > 50
Говоря наперёд, для фильтрации групп мы должны использовать оператор HAVING:
SELECT 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 по цене до применения группировки и лишь затем вычислить среднюю стоимость групп оставшегося жилья:
SELECT 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 |
SELECT [константы, агрегатные_функции, поля_группировки] FROM имя_таблицы WHERE условия_на_ограничения_строк GROUP BY поля_группировки HAVING условие_на_ограничение_строк_после_группировки ORDER BY условие_сортировки
Для примера давайте получим минимальную стоимость каждого типа жилья c телевизором. При этом нас интересуют только типы жилья, содержащие как минимум 5 жилых помещений, относящихся к ним.
Чтобы получить такой результат мы должны:
Сначала получить все данные из таблицы
SELECT ... FROM Rooms;
Затем выбрать из всех записей таблиц Room только интересующие нас, т.е. только жильё с телевизором
SELECT ... FROM Rooms WHERE has_tv = True
Затем сгруппировать данные записи о жилых помещений по их типу
SELECT ... FROM Rooms WHERE has_tv = True GROUP BY home_type
После этого отфильтровать полученных группы по условию, что нас интересуют групп, имеющие как минимум 5 представителей
SELECT .
.. FROM Rooms WHERE has_tv = True GROUP BY home_type HAVING COUNT(*) >= 5И под конец, посмотреть что нас просят в задании и, соответственно, добавить вывод необходимой информации. В нашем случае, нам необходимо вывести название типа жилья и его минимальную стоимость.
SELECT home_type, MIN(price) as min_price FROM Rooms WHERE has_tv = True GROUP BY home_type HAVING COUNT(*) >= 5;
Предложение SQL HAVING (с примерами)
В этом руководстве вы узнаете о предложении SQL HAVING с помощью примеров.
Предложение SQL HAVING
используется, если нам нужно отфильтровать набор результатов на основе агрегатных функций, таких как MIN() и MAX(), SUM() и AVG() и COUNT().
Пример
-- выберите клиентов с одинаковым именем на основе их возраста ВЫБЕРИТЕ COUNT(возраст) AS Count, first_name ОТ клиентов СГРУППИРОВАТЬ ПО first_name КОЛИЧЕСТВО(возраст) > 1;
Здесь команда SQL
- подсчитывает
возраст
каждой строки и группирует их поfirst_name
- возвращает набор результатов, если количество
age
больше, чем 1 (таким образом отфильтровывая клиентов с тем жеfirst_name
)
SQL HAVING Syntax
Синтаксис предложения SQL HAVING
:
SELECT AggFunc(column), extra_columns ИЗ таблицы СГРУППИРОВАТЬ ПО target_column НАЛИЧИЕ условия
Здесь
-
AggFunc(столбец)
относится к любой агрегатной функции, примененной к столбцу -
extra_columns
— другие дополнительные столбцы для фильтрации -
GROUP BY
группирует данные поtarget_column
-
НАЛИЧИЕ условия
сравнивает столбец
Пример: SQL HAVING
-- выберите количество идентификаторов клиентов больше одного и соответствующую им страну ВЫБЕРИТЕ COUNT(идентификатор_клиента), страна ОТ клиентов СГРУППИРОВАТЬ ПО СТРАНАМ ИМЕЕТ COUNT(customer_id) > 1;
Здесь команда SQL:
- подсчитывает количество строк, группируя их по странам
- возвращает набор результатов, если их число
Примечание: Предложение HAVING
было введено, поскольку предложение WHERE
не поддерживает агрегатные функции. Кроме того, перед предложением HAVING
необходимо использовать GROUP BY
. Чтобы узнать больше, посетите SQL GROUP BY.
SQL HAVING vs. WHERE
HAVING Пункт | ГДЕ Пункт |
---|---|
Предложение HAVING проверяет условие для группы строк . | Предложение WHERE проверяет условие в каждой отдельной строке . |
HAVING используется с агрегатными функциями. | Предложение WHERE нельзя использовать с агрегатными функциями. |
Предложение HAVING выполняется после предложения GROUP BY . | Предложение WHERE выполняется перед предложением GROUP BY . |
Давайте рассмотрим пример,
Мы можем написать предложение WHERE
для фильтрации строк, в которых значение сумма в таблице Orders меньше 500 : 9 0003
ВЫБЕРИТЕ идентификатор_клиента, количество ОТ заказов ГДЕ сумма < 500;
Но с предложением HAVING
мы можем использовать агрегатную функцию, такую как SUM
, чтобы вычислить сумму сумм в таблице заказов и получить общую стоимость заказа менее 500 для каждого клиента:
SELECT customer_id , СУММ(сумма) КАК итого ОТ заказов СГРУППИРОВАТЬ ПО customer_id СУММА(сумма) < 500;
SQL ИМЕЕТ Пункт
Предложение HAVING включает одно или несколько условий, которые должны быть ИСТИННЫ для групп записей. Это похоже на предложение WHERE предложения GROUP BY. Единственное отличие состоит в том, что предложение WHERE нельзя использовать с агрегатными функциями, тогда как предложение HAVING может использовать агрегатные функции.
Предложение HAVING всегда следует за предложением GROUP BY и перед предложением ORDER BY.
Синтаксис:
ВЫБЕРИТЕ столбец1, столбец2,... столбецN ОТ имя_таблицы [ГДЕ] [ГРУППИРОВАТЬ ПО столбцу1, столбцу2...столбцуN] [ИМЕЕТ условия] [СОРТИРОВАТЬ ПО]
- Предложение HAVING используется для фильтрации группирующих записей.
- Предложение HAVING должно стоять после предложения GROUP BY и перед предложением ORDER BY.
- Предложение HAVING может включать одно или несколько условий.
- Условие HAVING может включать только те столбцы, которые используются с предложением GROUP BY. Чтобы использовать другие столбцы в условии HAVING, используйте с ними агрегатные функции.
Для демонстрационных целей мы будем использовать следующую таблицу Employee
во всех примерах.
Таблица сотрудников
Эмпид | Имя | Фамилия | Электронная почта | Телефон № | Зарплата | ИД отдела |
---|---|---|---|---|---|---|
1 | 'Джон' | 'Король' | '[электронная почта защищена]' | '650. 127.1834' | 33000 | 1 |
2 | 'Джеймс' | «Бонд» | 1 | |||
3 | 'Нина' | 'Кочхар' | '[электронная почта защищена]' | '123.456.4568' | 17000 | 2 |
4 | 'Лекс' | 'Де Хаан' | '[электронная почта защищена]' | '123.000.4569' | 15000 | 1 |
5 | 'Амит' | 'Патель' | 18000 | 1 | ||
6 | 'Абдул' | 'Калам' | '[электронная почта защищена]' | '123. 123.0000' | 25000 | 2 |
В разделе GROUP BY мы использовали следующий запрос для получения количества сотрудников в каждом отделе, как показано ниже.
ВЫБРАТЬ DeptId, COUNT(EmpId) как «Число сотрудников» ОТ Сотрудника СГРУППИРОВАТЬ ПО DeptId;
ИД отдела | Количество сотрудников |
---|---|
1 | 4 |
2 | 2 |
Теперь, чтобы отфильтровать результат вышеуказанного запроса GROUP BY, используйте предложение HAVING с агрегатной функцией, как показано ниже.
ВЫБРАТЬ DeptId, COUNT(EmpId) как «Число сотрудников» ОТ Сотрудника СГРУППИРОВАТЬ ПО DeptId; СЧЕТЧИК (EmpId) > 2
Обратите внимание, что мы использовали агрегатную функцию COUNT()
в предложении HAVING, поскольку EmpId
не включен в предложение GROUP BY.