В чем разница между HAVING и WHERE в SQL?

В чем разница между HAVING и WHERE в заявлении SQL SELECT?

Обновлено: Я отметил ответ Стивена как правильный, поскольку он содержал ключевой бит информации по ссылке:

When GROUP BY is not used, HAVING behaves like a WHERE clause

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

Цитируемая вами строка вовсе не является ключевым моментом. Ключевой бит, как указал wcm, заключается в том, что HAVING является фильтром постагрегации, тогда как WHERE является фильтром до агрегирования.

Nick Chammas 25.01.2012 23:23

эта ссылка помогла мне понять это лучше, чем все комментарии ниже, думал, что кто-то может получить помощь от этого codeproject.com/Articles/25258/…

Lijin Durairaj 25.08.2016 00:50
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
267
2
309 211
19
Перейти к ответу Данный вопрос помечен как решенный

Ответы 19

HAVING используется, когда вы используете агрегат, такой как GROUP BY.

SELECT edc_country, COUNT(*)
FROM Ed_Centers
GROUP BY edc_country
HAVING COUNT(*) > 1
ORDER BY edc_country;

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

Ознакомьтесь с этим ссылка w3schools для получения дополнительной информации

Синтаксис:

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

Такой запрос:

SELECT column_name, COUNT( column_name ) AS column_name_tally
  FROM table_name
 WHERE column_name < 3
 GROUP 
    BY column_name
HAVING COUNT( column_name ) >= 3;

... может быть переписан с использованием производной таблицы (без HAVING) следующим образом:

SELECT column_name, column_name_tally
  FROM (
        SELECT column_name, COUNT(column_name) AS column_name_tally
          FROM table_name
         WHERE column_name < 3
         GROUP 
            BY column_name
       ) pointless_range_variable_required_here
 WHERE column_name_tally >= 3;

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

onedaywhen 28.11.2011 14:01
Ответ принят как подходящий

HAVING specifies a search condition for a group or an aggregate function used in SELECT statement.

Источник

Я использую HAVING для ограничения запроса на основе результатов агрегатной функции. НАПРИМЕР. выберите * в группе blahblahblah, ЧТО-ТО имея счет (ЧТО-ТО)> 0

От здесь.

the SQL standard requires that HAVING must reference only columns in the GROUP BY clause or columns used in aggregate functions

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

Источник сообщает: «Использование позиций столбцов не рекомендуется, поскольку синтаксис был удален из стандарта SQL». К сожалению, это неправильно: из Стандарта никогда ничего не удаляется, и по иронии судьбы HAVING все еще существует спустя десятилетия после того, как он был «устарел» производными таблицами.

onedaywhen 18.05.2016 15:06

Немного педантично, но цитата неверна, например. рассмотрим SELECT 1 FROM T HAVING COUNT(*) >= 1; - не ссылается ни на столбцы в предложении GROUP BY (его нет), ни на столбцы в агрегатных функциях (запрос вообще не ссылается на столбцы).

onedaywhen 18.05.2016 15:10

HAVING: используется для проверки условий после, выполняется агрегация. ГДЕ: используется для проверки условий до, когда происходит агрегирование.

Этот код:

select City, CNT=Count(1)
From Address
Where State = 'MA'
Group By City

Дает вам таблицу всех городов в Массачусетсе и количество адресов в каждом городе.

Этот код:

select City, CNT=Count(1)
From Address
Where State = 'MA'
Group By City
Having Count(1)>5

Дает вам таблицу городов в Массачусетсе с более чем 5 адресами и количеством адресов в каждом городе.

Это должен быть принятый ответ. Различие между «иметь» и «где» сразу же проясняет это.

Paul 31.07.2018 23:17

WHERE применяется как ограничение для набора, возвращаемого SQL; он использует встроенные операции набора и индексы SQL и, следовательно, является самым быстрым способом фильтрации наборов результатов. По возможности всегда используйте WHERE.

ИМЕТЬ необходимо для некоторых агрегатных фильтров. Он фильтрует запрос ПОСЛЕ того, как sql извлекает, собирает и отсортировывает результаты. Следовательно, он намного медленнее, чем WHERE, и его следует избегать, за исключением тех ситуаций, которые этого требуют.

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

Поддержка производных таблиц на языке SQL означает, что ваше утверждение «HAVING необходимо для некоторых агрегатных фильтров» неверно.

onedaywhen 28.11.2011 14:03

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

davidcl 25.12.2011 20:26

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

Предикаты в предложении Have применяются к совокупному набору результатов ПОСЛЕ того, как он был сгенерирован. Вот почему условия предиката для агрегированных значений должны быть помещены в предложение Have, а не в предложение Where, и почему вы можете использовать псевдонимы, определенные в предложении Select в предложении Have, но не в предложении Where.

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

WHERE my_indexed_row = 123 покажет строки и автоматически выполнит «ORDER ASC» для других проиндексированных строк.

HAVING my_indexed_row = 123 показывает все, от самой старой «вставленной» строки до самой новой, без упорядочивания.

Откуда вы знаете, что это определенная разница между двумя, а не случайность реализации конкретного SQL-сервера, который вы использовали?

JdeBP 12.11.2019 14:55

Я только что тестировал на MariaDB. Думаю, именно тот SQL-сервер, который я использовал 8 лет назад, дал разные результаты.

Simmoniz 14.11.2019 21:29

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

Теперь рассмотрим удаление WHERE из языка. На этот раз большинство существующих запросов нужно будет переписать без очевидной альтернативной конструкции. Кодерам придется проявить творческий подход, например, внутреннее соединение с таблицей, которая, как известно, содержит ровно одну строку (например, DUAL в Oracle), с использованием предложения ON для имитации предыдущего предложения WHERE. Такие конструкции будут надуманными; было бы очевидно, что в языке чего-то не хватает, и в результате ситуация ухудшится.

TL; DR мы можем потерять HAVING завтра, и все будет не хуже, возможно, лучше, но этого нельзя сказать о WHERE.


Из ответов здесь кажется, что многие люди не понимают, что предложение HAVING может использоваться без предложения GROUP BY. В этом случае предложение HAVING применяется ко всему табличному выражению и требует, чтобы в предложении SELECT появлялись только константы. Обычно пункт HAVING включает агрегаты.

Это более полезно, чем кажется. Например, рассмотрите этот запрос, чтобы проверить, является ли столбец name уникальным для всех значений в T:

SELECT 1 AS result
  FROM T
HAVING COUNT( DISTINCT name ) = COUNT( name );

Есть только два возможных результата: если предложение HAVING истинно, то результатом будет одна строка, содержащая значение 1, в противном случае результатом будет пустой набор.

Будет ли это эквивалентно «ВЫБРАТЬ СЧЕТЧИК (РАЗЛИЧНОЕ имя) = СЧЕТЧИК (имя) ОТ T»?

MSpreij 28.12.2015 16:41

@MSpreij Не знаю, работает ли это для вас, но он не работает на SQL Server 2005, но первый работает

Joe 20.04.2016 15:30

Во время работы над проектом это тоже был мой вопрос. Как указано выше, ИМЕЮЩИЕ проверяет условие для уже найденного результата запроса. Но ГДЕ предназначен для проверки условия во время выполнения запроса.

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

usertable{ int userid, date datefield, int dailyincome }

Допустим, в таблице есть следующие строки:

1, 2011-05-20, 100

1, 2011-05-21, 50

1, 2011-05-30, 10

2, 2011-05-30, 10

2, 2011-05-20, 20

Теперь мы хотим получить userid и sum(dailyincome), у которых sum(dailyincome)>100

Если мы напишем:

SELECT userid, sum(dailyincome) FROM usertable WHERE sum(dailyincome)>100 GROUP BY userid

Это будет ошибкой. Правильный запрос будет:

SELECT userid, sum(dailyincome) FROM usertable GROUP BY userid HAVING sum(dailyincome)>100

Разница между ними заключается во взаимосвязи с предложением GROUP BY:

  • ГДЕ предшествует GROUP BY; SQL оценивает предложение WHERE перед группировкой записей.

  • HAVING следует после GROUP BY; SQL оценивает HAVING после того, как группирует записи.

select statement diagram

использованная литература

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

Paul Sweatte 08.07.2016 16:29

Пример запроса из моего ответа на этот вопрос: SELECT 1 AS result FROM T HAVING... - на вашей диаграмме я не могу добраться до HAVING, не пройдя через GROUP BY, но в моем совершенно правильном и полезном запросе нет GROUP BY. Незначительный момент: у вас нет возможности включать буквальные значения в предложение SELECT.

onedaywhen 03.10.2016 12:28

@onedaywhen Поскольку тебе известно о неявном GROUP BY, почему вы не упомянули об этом? Вы знаете, ожидаете ли вы это поведение или нет?

Paul Sweatte 03.10.2016 18:50

Мне кажется, вы цитируете меня вне контекста. Вопрос касался очевидного отклонения mySQL от Стандарта, все, кроме последнего абзаца моего ответа, описывают стандартное поведение, а последний намекает на «неявное предложение GROUP BY упомянутые в других ответах». Вы говорите, что ваша диаграмма предназначена для описания (всего) неявного поведения? Разве не было бы более полезным придерживаться только того кода, который вам нужно написать, чтобы получить желаемое поведение?

onedaywhen 04.10.2016 10:41

... Я не знаю, о каком поведении вы говорите во второй ссылке. Желаемый результат состоит в том, чтобы вы исправили диаграмму, чтобы показать действительный (явный) путь, о котором я упоминал. Подумайте об этом: диаграмма охватывает весь запрос, но вопрос интересует только часть WHERE->HAVING, поэтому я думаю, что заслуживает пристального внимания к деталям. Если вы считаете, что мой ответ неверен, отредактируйте его или опубликуйте предлагаемое исправление в комментариях.

onedaywhen 04.10.2016 10:47

@onedaywhen Во второй ссылке упоминается HAVING condition applied to rows rather than groups. Это нестандартно или стандартно? Всегда ли, никогда или иногда неявная GROUP BY? Является ли это поведение на 100% совместимым со стандартами, устаревшим, антипаттерном, зависимым от реализации или перспективным в будущем?

Paul Sweatte 04.10.2016 15:22

«Условие HAVING применяется к строкам, а не к группам» для меня звучит неправильно. ИМО, поведение лучше изложить в том же ответе: «Предложение имеющее исключает строки из окончательных результатов, которые не соответствуют его условиям поиска», просто так, 100% стандартное соответствие. Если нет GROUP BY, значит, неявная группировка отсутствует. Но я все еще немного смущен тем, как это связано с вашей диаграммой, отсутствует действительный путь.

onedaywhen 05.10.2016 14:31

Быстрое доказательство: CREATE TABLE T (c CHAR(1)); INSERT INTO T VALUES ('a'),('a'); SELECT 'true' FROM T HAVING COUNT (c) = 2; должен быть результатом с одной строкой и одним столбцом, показывающим true, потому что условие поиска не удаляет строки, то есть не применяет неявную группу по (если бы он был сгруппирован, то COUNT(c) был бы 1, условие поиска завершилось бы ошибкой, т.е. результат нулевой строки ).

onedaywhen 05.10.2016 15:15

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

JdeBP 12.11.2019 14:57

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

Предложение WHERE не работает для агрегатных функций
означает: вы не должны так использовать бонус: название таблицы

SELECT name  
FROM bonus  
GROUP BY name  
WHERE sum(salary) > 200  

ЗДЕСЬ Вместо предложения WHERE вы должны использовать HAVING ..

без использования предложения GROUP BY предложение HAVING работает как предложение WHERE

SELECT name  
FROM bonus  
GROUP BY name  
HAVING sum(salary) > 200  

Когда GROUP BY не используется, пункты WHERE и HAVING по существу эквивалентны.

Однако при использовании GROUP BY:

  • Предложение WHERE используется для фильтрации записей из результата. В фильтрация происходит до того, как будут произведены какие-либо группировки.
  • Предложение HAVING используется для фильтрации значений из группы (т.е. условия проверки после выполнения объединения в группы).

Ресурс от Здесь

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

Nagendra Kumar 17.09.2019 13:51

Один из способов подумать об этом состоит в том, что предложение Have является дополнительным фильтром к предложению where.

Предложение ГДЕ используется для фильтрации записей из результата. Фильтр выполняется до того, как будут сделаны какие-либо группировки. Предложение ИМЕЮЩИЕ используется для фильтрации значений из группы

Разница ч / б WHERE и HAVING пункт:

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

Зачем нужна оговорка HAVING?

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

Когда GROUP BY не используется, предложения WHERE и HAVING по существу эквивалентны.

Однако при использовании GROUP BY:

  • Предложение WHERE используется для фильтрации записей из результата. В фильтрация происходит до того, как будут произведены какие-либо группировки.
  • Предложение HAVING используется для фильтрации значений из группы (т. е. для проверки условий после агрегирование в группы выполнено).

Предложение Where используется для фильтрации строк по всей базе данных. Но предложение Have используется для фильтрации строк из определенной группы базы данных. Предложение Наличие также может помочь в совокупной функции, такой как мин / макс / среднее

подробнее .. в чем разница между WHERE и HAVINGв чем разница между WHERE и HAVING

Я здесь, если тебе нужна другая помощь

Uzair 19.08.2020 02:00

Почему тебе не понравился пост ??

Uzair 19.08.2020 02:00

Другие вопросы по теме