В дополнение к способности группировать данные с помощью предложения GROUP BY
, SQL также позволяет осуществлять фильтрацию — указывать, какие группы должны быть включены в результат, а какие исключены из него. Например, вам может понадобиться список клиентов, которые сделали хотя бы два заказа. Чтобы получить такие данные, необходим фильтр, относящийся к целой группе, а не к отдельным строкам.
В данном случае предложение WHERE
использовать нельзя, поскольку фильтры WHERE
указывают строки, а не группы. Собственно говоря, WHERE
"не знает", что такое группы.
Но тогда что можно использовать вместо предложения WHERE
? SQL предлагает другое предложение, подходящее для этих целей: предложение HAVING
. Предложение HAVING
очень похоже на предложение WHERE
. И действительно, все типы выражений в предложении WHERE
могут быть также использованы с предложением HAVING
. Единственная разница состоит в том, что WHERE
фильтрует строки, a HAVING
— группы.
Пример:
Нужно найти страницы с одинаковыми адресами, как выглядит часть таблицы (таблица test):
id | name | url |
---|---|---|
1 | Главная | / |
2 | Раздел | /razdel |
3 | Новость | /news |
4 | Еще один раздел | /razdel |
Теперь напишем запрос который выведит нужные записи:
select `url` from `test` group by `url` having count(*)>=2
Данный запрос группирует все записи по полю url
и выводит те значения поля url
которые встречаются 2 или более раз.
Результат будет:
url |
---|
/razdel |
Как видите, предложение WHERE
здесь не работает, поскольку фильтрация основана на итоговом значении группы, а не на значениях указанных строк.
Вот как это можно рассматривать: WHERE
фильтрует до того, как данные будут сгруппированы, a HAVING
фильтрует после того, как данные были сгруппированы. Это— важное различие; строки, которые были выброшены по предложению WHERE
, не будут включены в группу, иначе это могло бы изменить вычисляемые значения, которые, в свою очередь, могли бы повлиять на фильтрацию групп в предложении HAVING
.
Статья написана на основе главы "Фильтрующие группы" из книги Освой самостоятельно SQL.