Чем отличается where от having
Перейти к содержимому

Чем отличается where от having

  • автор:

HAVING

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

Другими словами применяется для агрегатных функций(COUNT(), MAX() . ) и столбцов указанных в выражении SELECT и обработанных GROUP BY. Если нужно использовать что-то, что не указанно в SELECT, то лучше использовать WHERE.

Порядок выполнения такой:
1. В SELECT указываем нужные столбцы или агрегатные функции(то с чем будем работать в GROUP BY и HAVING)
2. В GROUP BY пишем по какому столбцу или функции их группируем
3. В HAVING пишем условие фильтровки результата GROUP BY

Применяется последним и не оптимизируется. При использовании не по назначению на больших таблицах будут жуткие тормоза.

SELECT COUNT(*) AS `c`, `title` FROM `razdel` GROUP BY `sort` HAVING `c` > 1;

Здесь мы создаём псевдоним:

COUNT(*) AS `c`

который в дальнейшем используем в выражении:

HAVING `c` > 1;

// идентично:
// HAVING COUNT(*) > 1;

Чем отличается WHERE от HAVING?

SQL_Deep_28.12_site-5020-c73a25.png

Обсудим такой популярный вопрос на собеседовании, как «Чем отличается WHERE от HAVING»?

 
SELECT username, COUNT(*) FROM table WHERE username = ‘Anna’ GROUP BY username HAVING COUNT(*)>1

Ой, скажет кто-то, зачем же спрашивать такие банальности? Как ни странно, довольно много разработчиков даже с сертификатами по SQL quering не понимают, что происходит в HAVING.

Давайте разберёмся. В сущности, HAVING очень похож на WHERE - это тоже фильтр. Вы можете написать в HAVING name = ‘Anna’, как и в WHERE, и ошибки не будет.

В чём же ключевое различие?

Во-первых, в HAVING и только в нём можно писать условия по агрегатным функциям (SUM, COUNT, MAX, MIN и т. д.). То есть если вы хотите сделать что-то вроде COUNT() > 10, то это возможно сделать только в HAVING*.

"Почему бы не оставить только HAVING?" - спросите вы. Всё кроется в том, как SQL Server выполняет запрос, в каком порядке происходит его разбор и работа с данными. WHERE выполняется до формирования групп GROUP BY. Это нужно для того, чтобы можно было оперировать как можно меньшим количеством данных и сэкономить ресурсы сервера и время пользователя.

Следующим этапом формируются группы, которые указаны в GROUP BY. После того как сформированы группы, можно накладывать условия на результаты агрегатных функций. И тут как раз наступает очередь HAVING: выполняются условия, которые вы задали.

Главное отличие HAVING от WHERE в том, что в HAVING можно наложить условия на результаты группировки, потому что порядок исполнения запроса устроен таким образом, что на этапе, когда выполняется WHERE, ещё нет групп, а HAVING выполняется уже после формирования групп.

Остались вопросы? Пишите их в комментариях!

Используйте предложения HAVING и WHERE в одном запросе (визуальные инструменты базы данных)

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

Предложение HAVING похоже WHERE на предложение, но применяется только к группам в целом (то есть к строкам в результирующем наборе, представляющего группы), в то время WHERE как предложение применяется к отдельным строкам. Запрос может содержать как предложение, WHERE так и HAVING предложение. В этом случае:

  • Предложение WHERE применяется сначала к отдельным строкам в таблицах или табличных объектах на панели диаграммы . Группируются только строки, соответствующие условиям в предложении WHERE .
  • Затем HAVING предложение применяется к строкам в результирующем наборе. В выходных данных запроса отображаются только группы, соответствующие HAVING условиям. Предложение можно применять HAVING только к столбцам, которые также отображаются в предложении GROUP BY или в агрегатной функции.

Указание предложения WHERE и HAVING для двух присоединенных таблиц

База данных, используемая в этой статье, является базой данных, доступной pubs из Northwind и пабов примеры баз данных для Microsoft SQL Server на GitHub.

Например, соединяются таблицы titles и publishers , чтобы создать запрос, показывающий среднюю цену книги для группы издателей. Требуется средняя цена книги только определенной группы издателей — например, только издателей в штате Калифорния. И даже тогда, вы хотите увидеть среднюю цену только в том случае, если это более $ 10,00.

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

SELECT titles.pub_id, AVG(titles.price) FROM titles INNER JOIN publishers ON titles.pub_id = publishers.pub_id WHERE publishers.state = 'CA' GROUP BY titles.pub_id HAVING AVG(price) > 10; 

В visual Database Tools of SQL Server Management Studio можно создавать оба HAVING предложения и WHERE предложения в области условий . По умолчанию при указании условия поиска для столбца условие становится частью HAVING предложения. Однако условие можно изменить, чтобы быть предложением WHERE .

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

Указание условия WHERE в агрегатном запросе

  1. Укажите группы для запроса. Дополнительные сведения см. в разделе Группирование строк в результатах запроса (визуальные инструменты для баз данных).
  2. Если он еще не находится в области условий , добавьте столбец, на котором вы хотите создать WHERE условие.
  3. Очистите столбец Вывод , если столбец данных не является частью предложения GROUP BY или не входит в агрегатную функцию.
  4. В столбце "Фильтр" укажите WHERE условие. Конструктор запросов и представлений добавляет условие в HAVING предложение инструкции SQL.

Примечание. В качестве примера данной процедуры показан запрос, соединяющий две таблицы titles и publishers .

На этом этапе запроса инструкция SQL содержит HAVING предложение:

SELECT titles.pub_id, AVG(titles.price) FROM titles INNER JOIN publishers ON titles.pub_id = publishers.pub_id GROUP BY titles.pub_id HAVING publishers.state = 'CA' 
SELECT titles.pub_id, AVG(titles.price) FROM titles INNER JOIN publishers ON titles.pub_id = publishers.pub_id WHERE publishers.state = 'CA' GROUP BY titles.pub_id; 

Связанный контент

  • SELECT — НАЛИЧИЕ (Transact-SQL)
  • Результаты запросов сортировки и группирования (визуальные инструменты для баз данных)
  • Резюмирование результатов запросов (визуальные инструменты для баз данных)

Чем отличается HAVING от WHERE?

Почему данную выборку нельзя переписать с использованием WHERE?

SELECT StudentId FROM EXAM_RESULT GROUP BY StudentID HAVING MIN(Mark) = 5
  • Вопрос задан более трёх лет назад
  • 20871 просмотр

Комментировать
Решения вопроса 3
Сергей Горностаев @sergey-gornostaev Куратор тега SQL
Седой и строгий

Основное отличие WHERE от HAVING заключается в том, что WHERE сначала выбирает строки, а затем группирует их и вычисляет агрегатные функции (таким образом, она отбирает строки для вычисления агрегатов), тогда как HAVING отбирает строки групп после группировки и вычисления агрегатных функций. Как следствие, предложение WHERE не должно содержать агрегатных функций; не имеет смысла использовать агрегатные функции для определения строк для вычисления агрегатных функций. Предложение HAVING, напротив, всегда содержит агрегатные функции. (Строго говоря, вы можете написать предложение HAVING, не используя агрегаты, но это редко бывает полезно. То же самое условие может работать более эффективно на стадии WHERE.)

Ответ написан более трёх лет назад
Комментировать
Нравится 4 Комментировать

Maksclub

maksfedorov.ru

Чтобы понять, что у студента Mark=5 -- минимальный, нужно сгруппировать значения, вдруг не минимальный (помимо проверки -- есть он или нет).
То есть чтобы полностью ваше условие проверить, нужно точно группировать, WHERE просто проверит -- есть такое значение или нет и выведет студентов, у которых есть

WHERE же используется движком на момент выборки, физически не возможно узнать минимальное значение

HAVING же уже работает с агрегирующими функциями, то есть мы сгруппировали, посчитали нужной функцией (минимальное значение в вашем случае), а HAVING уже выдал с условием этого подсчета

Ответ написан более трёх лет назад
Комментировать
Нравится 1 Комментировать
Готовые решения - не подаю, но.

Можно и переписать. но в виде извращенного каскада вложенных селектов:
- внутренний будет вываливать сгруппированные StudentId и MIN(Mark)
- внешний будет селектить StudentId с условие where

Ответ написан более трёх лет назад
Комментировать
Нравится 1 Комментировать
Ответы на вопрос 0
Ваш ответ на вопрос

Войдите, чтобы написать ответ

sql

  • SQL

Где ошибка в SQL запросе?

  • 2 подписчика
  • 3 часа назад
  • 94 просмотра

php

  • PHP
  • +1 ещё

Как вывести дату на диаграмме, если ее нет в базе?

  • 1 подписчик
  • 15 янв.
  • 62 просмотра

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *