1с в чем заключается разница между предложениями где where и имеющие having
В чем разница между HAVING и WHERE в SQL SELECT заявление?
РЕДАКТИРОВАТЬ: Я отметил ответ Стивена как правильный, поскольку он содержал ключевой бит информации по ссылке:
когда GROUP BY не используется, HAVING ведет себя как WHERE пункт
Ситуация, которую я видел WHERE в не было GROUP BY и здесь началось мое замешательство. Конечно, пока вы этого не узнаете, вы не можете указать это в вопросе.
HAVING определяет условие поиска для группы или агрегатной функции, используемой в операторе SELECT.
HAVING: используется для проверки условий после происходит агрегирование.
ГДЕ: используется для проверки условий до происходит агрегирование.
Дает вам таблицу всех городов в Массачусетсе и количество адресов в каждом городе.
Дает вам таблицу городов в штате Массачусетс с более чем 5 адресами и количеством адресов в каждом городе.
Разница номер один для меня: если HAVING был удален из языка SQL, тогда жизнь продолжалась более-менее как прежде. Конечно, запросы меньшинства должны быть переписаны с использованием производной таблицы, CTE и т. Д., Но в результате их, возможно, будет легче понять и поддерживать. Возможно, потребуется переписать код оптимизатора поставщиков, чтобы учесть это, что снова является возможностью для улучшений в отрасли.
А теперь подумайте об удалении WHERE с языка. На этот раз большинство существующих запросов пришлось бы переписать без очевидной альтернативной конструкции. Кодеры должны проявить творческий подход, например, внутреннее соединение с таблицей, содержащей ровно одну строку (например, DUAL в Oracle) с помощью ON пункт для моделирования предыдущего WHERE пункт. Такие конструкции будут надуманными; Было бы очевидно, что в языке чего-то не хватает, и в результате ситуация ухудшится.
TL; DR мы можем проиграть HAVING завтра и все будет не хуже, а может и лучше, но то же самое нельзя сказать о WHERE .
Это более полезно, чем кажется. Например, рассмотрите этот запрос, чтобы проверить, name столбец уникален для всех значений в T :
Есть только два возможных результата: если HAVING предложение истинно, то результатом будет одна строка, содержащая значение 1 , иначе результатом будет пустой набор.
Предложение HAVING было добавлено в SQL, поскольку ключевое слово WHERE нельзя было использовать с агрегатными функциями.
Проверьте эту ссылку w3schools для получения дополнительной информации
. может быть переписан с использованием производной таблицы (без указания HAVING ) как это:
- 3 Вы немного упустили суть: HAVING был добавлен, потому что производные таблицы не были добавлены к языку, и до тех пор, пока они не были преобразованы в SQL, он не был реляционно завершенным, и когда они неизбежно были HAVING стал избыточным.
Разница между ними заключается в отношении к предложению GROUP BY:
WHERE предшествует GROUP BY; SQL оценивает предложение WHERE перед группировкой записей.
HAVING следует после GROUP BY; SQL оценивает HAVING после того, как группирует записи.
Рекомендации
Синтаксис оператора SQLite SELECT / железнодорожная диаграмма
Синтаксис оператора Informix SELECT / железнодорожная диаграмма
HAVING используется, когда вы используете агрегат, такой как GROUP BY .
WHERE применяется как ограничение для набора, возвращаемого SQL; он использует встроенные операции и индексы SQL и, следовательно, является самым быстрым способом фильтрации наборов результатов. По возможности всегда используйте WHERE.
ИМЕТЬ необходимо для некоторых агрегатных фильтров. Он фильтрует запрос ПОСЛЕ того, как sql извлекает, собирает и отсортировывает результаты. Следовательно, он намного медленнее, чем WHERE, и его следует избегать, за исключением тех ситуаций, которые этого требуют.
SQL Server позволит вам обойтись без использования HAVING, даже если WHERE будет намного быстрее. Не делай этого.
Предложение WHERE не работает для агрегатных функций
означает: вы не должны использовать такой бонус: имя таблицы
HERE Вместо предложения WHERE вы должны использовать HAVING ..
без использования предложения GROUP BY предложение HAVING работает как предложение WHERE
Разница ч / б WHERE и HAVING пункт:
Основное различие между WHERE и HAVING пункт, WHERE используется для строковых операций и HAVING используется для операций с колонками.
Зачем нам нужны HAVING пункт?
Как мы знаем, агрегатные функции могут выполняться только для столбцов, поэтому мы не можем использовать агрегатные функции в WHERE пункт. Поэтому мы используем агрегатные функции в HAVING пункт.
когда GROUP BY не используется, WHERE и HAVING пункты по существу эквивалентны.
Однако когда GROUP BY используется:
- В WHERE Предложение используется для фильтрации записей из результата. Фильтрация происходит до создания каких-либо группировок.
- В HAVING Предложение используется для фильтрации значений из группы (т. е. для проверки условий после выполнения агрегации в группы).
- имеющий и где по существу не эквивалентны. он выдаст ошибку при выполнении. недопустимо в предложении HAVING, потому что он не содержится ни в агрегатной функции, ни в предложении GROUP BY.
Один из способов подумать об этом - предложение иметь как дополнительный фильтр к предложению where.
А ГДЕ Предложение используется для фильтрации записей из результата. Фильтр выполняется до того, как будут выполнены какие-либо группировки. А ИМЕЕТ предложение используется для фильтрации значений из группы
В агрегированном запросе (любой запрос, в котором используется агрегатная функция) Предикаты в предложении where оцениваются до создания агрегированного промежуточного набора результатов,
Предикаты в предложении Have применяются к совокупному набору результатов ПОСЛЕ того, как он был сгенерирован. Вот почему условия предиката для агрегированных значений должны быть помещены в предложение Have, а не в предложение Where, и почему вы можете использовать псевдонимы, определенные в предложении Select в предложении Have, но не в предложении Where.
У меня возникла проблема, и я обнаружил еще одно различие между WHERE и HAVING . На индексированные столбцы он действует иначе.
- Откуда вы знаете, что это определенная разница между двумя, а не случайность реализации конкретного SQL-сервера, который вы использовали?
- Я только что тестировал на MariaDB. Думаю, именно тот SQL-сервер, который я использовал 8 лет назад, дал разные результаты.
стандарт SQL требует, чтобы HAVING ссылался только на столбцы в предложении GROUP BY или столбцы, используемые в агрегатных функциях.
в отличие от предложения WHERE, которое применяется к строкам базы данных
Во время работы над проектом это тоже был мой вопрос. Как указано выше, ИМЕЕТ проверяет условие для уже найденного результата запроса. Но ГДЕ предназначен для проверки условия во время выполнения запроса.
Позвольте мне проиллюстрировать это примером. Предположим, у вас есть такая таблица базы данных.
Допустим, в таблице есть следующие строки:
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 s и sum(dailyincome) чья sum(dailyincome)>100
Если мы напишем:
ВЫБЕРИТЕ ИД пользователя, сумму (ежедневный доход) ИЗ таблицы пользователя ГДЕ сумма (ежедневный доход)> 100 ГРУППА ПО ИДЕНТИФИКАТОРУ ПОЛЬЗОВАТЕЛЯ
Это будет ошибкой. Правильный запрос будет:
ВЫБЕРИТЕ ИД пользователя, сумму (дневной доход) ИЗ таблицы пользователя ГРУППА ПО ИДЕНТИФИКАТОРУ ПОЛЬЗОВАТЕЛЯ ИМЕЕТ сумму (дневной доход)> 100
Предложение WHERE используется для сравнения значений в базовой таблице, тогда как предложение HAVING может использоваться для фильтрации результатов агрегатных функций в наборе результатов запроса. Щелкните здесь!
Когда GROUP BY не используется, предложения WHERE и HAVING по существу эквивалентны.
Однако, когда используется GROUP BY:
- Предложение WHERE используется для фильтрации записей из результата. Фильтрация происходит до создания каких-либо группировок.
- Предложение HAVING используется для фильтрации значений из группы (т. Е. Для проверки условий после выполнения агрегации в группы).
Я использую HAVING для ограничения запроса на основе результатов агрегатной функции. НАПРИМЕР. выберите * в группе blahblahblah, ЧТО-ТО имея счет (ЧТО-ТО)> 0
- 3 Вы должны быть уверены, прежде чем публиковать ответ. Это может ввести в заблуждение других.
Предложение Where используется для фильтрации строк по всей базе данных. Но предложение Have используется для фильтрации строк из определенной группы базы данных. Предложение Наличие также может помочь в совокупной функции, такой как мин / макс / среднее
для более подробной информации .. в чем разница между WHERE и HAVING, в чем разница между WHERE и HAVING
После прочтения это не дубликат Явных vs неявных SQL-соединений. Ответ может быть связан (или даже тем же), но вопрос отличается.
В чем разница и что должно идти в каждом?
Если я правильно понимаю теорию, оптимизатор запросов должен иметь возможность использовать как взаимозаменяемые.
ОТВЕТЫ
Ответ 1
Это не одно и то же.
Рассмотрим эти запросы:
Первый возвращает заказ и его строки, если они есть, для номера заказа 12345 . Второй будет возвращать все заказы, но только порядок 12345 будет иметь связанные с ним строки.
С помощью INNER JOIN статьи фактически эквивалентны. Однако только потому, что они функционально одинаковы, поскольку они дают одни и те же результаты, это не значит, что два вида предложений имеют одинаковый смысловой смысл.
Ответ 2
Вопросы для внешних соединений
а. WHERE : После соединения. Записи будут отфильтрованы после присоединения.
б. ON - До. Записи (из правой таблицы) будут отфильтрованы перед присоединением. Это может закончиться как null в результате (поскольку соединение OUTER).
Пример. Рассмотрим приведенные ниже таблицы:
a) Внутри предложения WHERE :
b) Внутри предложения JOIN
Ответ 3
В INNER JOIN они взаимозаменяемы, и оптимизатор будет их изменять по желанию.
В OUTER JOIN s они не обязательно взаимозаменяемы, в зависимости от того, на какой стороне соединения они зависят.
Я помещаю их в любом месте в зависимости от читаемости.
Ответ 4
Я делаю это так:
Всегда помещайте условия соединения в предложение ON , если вы выполняете INNER JOIN . Поэтому не добавляйте никаких условий WHERE к предложению ON, поместите их в WHERE .
Если вы делаете LEFT JOIN , добавьте любые условия WHERE в предложение ON для таблицы в правой части соединения. Это необходимо, поскольку добавление предложения WHERE, которое ссылается на правую сторону объединения, преобразует соединение в INNER JOIN.
Исключение составляют случаи, когда вы ищете записи, которых нет в конкретной таблице. Вы бы добавили ссылку на уникальный идентификатор (который никогда не равен NULL) в таблице RIGHT JOIN к предложению WHERE следующим образом: WHERE t2.idfield IS NULL . Таким образом, единственный раз, когда вы должны ссылаться на таблицу с правой стороны объединения, это найти те записи, которых нет в таблице.
Ответ 5
На внутреннем соединении они означают одно и то же. Однако вы получите разные результаты во внешнем соединении в зависимости от того, добавили ли вы условие соединения в предложение WHERE и ON. Взгляните на этот связанный вопрос и этот ответ (по мне).
Я думаю, что наиболее разумно иметь привычку всегда ставить условие соединения в предложение ON (если это не внешнее соединение, а вы действительно хотите его в предложении where), поскольку оно делает его более ясным для кого-либо прочитав ваш запрос о том, какие условия объединяются в таблицы, а также помогает предотвратить предложение WHERE из десятков строк.
Ответ 6
Эта статья ясно объясняет разницу. Это также объясняет "ON join_condition против WHERE join_condition или join_alias имеет значение null".
Предложение WHERE фильтрует результат предложения FROM вместе с JOIN, а предложение ON используется для получения результата таблицы между таблицами FROM и JOIN.
- Если вы хотите получить результат таблицы, который объединяет две таблицы, тогда вам следует воспользоваться предложением ON, чтобы определить, как таблицы объединяются. Конечно, это также может фильтровать строки из исходной таблицы, например, в случае INNER JOIN.
- Если вы хотите отфильтровать продукт объединения обеих сторон, вам следует использовать предложение WHERE.
Ответ 7
Существует большая разница между предложением where и on, когда дело доходит до левого соединения.
Здесь fid является идентификатором таблицы t2.
Запрос в разделе "on":
Запрос в разделе "where where":
Ясно, что, первый запрос возвращает запись из t1 и ее зависимую строку из t2, если таковая имеется, для строки t1.v = 'K'.
Второй запрос возвращает строки из t1, но только для t1.v = 'K' будет иметь любую связанную с ним строку.
Ответ 8
В терминах оптимизатора не должно быть никакого значения, определяете ли вы свои предложения о соединении с помощью ON или WHERE.
Однако, IMHO, я думаю, что гораздо проще использовать предложение ON при выполнении объединений. Таким образом, у вас есть определенный раздел вашего запроса, который определяет, как обрабатывается соединение, и смешивается с остальными предложениями WHERE.
Ответ 9
Я думаю, что это эффект последовательности соединений. В случае с верхним левым соединением SQL do Left сначала присоединяется, а затем выполняет фильтр. В нижнем случае сначала найдите Orders.ID = 12345, а затем присоединитесь.
Ответ 10
В SQL предложения "WHERE" и "ON" являются разновидностями условных выражений состояния, но основное отличие между ними заключается в том, что выражение "Where" используется в операторах выбора/обновления для указания условий, тогда как предложение "ON" используется в соединениях, где он проверяет или проверяет, совпадают ли записи в таблицах назначения и источника, до объединения таблиц
Например: - "ГДЕ"
Например: - "ВКЛ"
Есть две таблицы employee и employee_details, соответствующие столбцы - employee_id.
Надеюсь, я ответил на ваш вопрос. Возврат для любых разъяснений.
Ответ 11
Для внутреннего соединения WHERE и ON можно использовать взаимозаменяемо. Фактически, можно использовать ON в коррелированном подзапросе. Например:
Это (IMHO), совершенно сбивающее с толку человека, и очень легко забыть связать table1 с чем угодно (потому что в таблице "драйвер" нет предложения "on"), но это законно.
Ответ 12
для лучших таблиц эффективности должен быть специальный индексный столбец для использования для JOINS.
поэтому если столбец, на котором вы устанавливаете условие, не является одним из этих индексированных столбцов, тогда я подозреваю, что лучше хранить его в WHERE.
поэтому вы присоединяетесь к использованию индексированных столбцов, а затем после JOIN вы запускаете условие в индексированном столбце none.
Ответ 13
Обычно фильтрация обрабатывается в предложении WHERE, когда две таблицы уже объединены. Однако возможно, что вы захотите отфильтровать одну или обе таблицы перед тем, как присоединиться к ним. то есть предложение where применяется ко всему набору результатов, тогда как предложение on относится только к рассматриваемому соединению.
Ответ 14
Я думаю, что это различие лучше всего объяснить с помощью логического порядка операций в SQL, который упрощен:
- FROM (включая объединения)
- WHERE
- GROUP BY
- Скопления
- HAVING
- WINDOW
- SELECT
- DISTINCT
- UNION , INTERSECT , EXCEPT
- ORDER BY
- OFFSET
- FETCH
Объединения - это не предложение оператора select, а оператор внутри FROM . Таким образом, все предложения ON принадлежащие соответствующему оператору JOIN , "уже произошли" логически к тому времени, когда логическая обработка достигает WHERE . Это означает, что, например, в случае LEFT JOIN семантика внешнего соединения уже произошла к тому времени, когда было применено WHERE .
LEFT JOIN самом деле не имеет никакого полезного эффекта, потому что даже если актер не сыграл в фильме, он будет отфильтрован, так как его FILM_ID будет NULL а WHERE отфильтрует такую строку. Результат примерно такой:
Т.е. как будто мы внутренне соединили две таблицы. Если мы переместим предикат фильтра в предложении ON , теперь он станет критерием для внешнего соединения:
Это означает, что результат будет содержать актеров без каких-либо фильмов или без каких-либо фильмов с FILM_ID < 10
Короче
Всегда ставьте свой предикат там, где это логично.
Ответ 15
Давайте рассмотрим эти таблицы:
id_A - это внешний ключ таблицы A
Написание этого запроса:
Предоставим такой результат:
То, что находится в A, но не в B, означает, что есть нулевые значения для B.
Теперь давайте рассмотрим конкретную деталь в B.id_A и B.id_A ее из предыдущего результата:
Написание этого запроса:
Предоставим такой результат:
Потому что это удаляет во внутреннем соединении значения, которых нет в B.id_A = SpecificPart
Теперь давайте изменим запрос на этот:
Поскольку весь результат фильтруется по B.id_A = SpecificPart удаляя части B.id_A = NULL , которые находятся в A, а не в B
Ответ 16
Вы пытаетесь объединить данные или отфильтровать данные?
Для удобства чтения имеет смысл выделить эти варианты использования в ON и WHERE соответственно.
- объединить данные в ПО
- фильтровать данные в ГДЕ
Это может стать очень трудным для чтения запроса, в котором в условии WHERE существуют условие JOIN и условие фильтрации.
С точки зрения производительности разницы не должно быть, хотя разные типы SQL иногда обрабатывают планирование запросов по-разному, поэтому стоит попробовать ¯\_(ツ)_/¯ (помните, что кеширование влияет на скорость запроса)
Также, как отметили другие, если вы используете внешнее объединение, вы получите другие результаты, если вы поместите условие фильтра в предложение ON, поскольку оно влияет только на одну из таблиц.
Ответ 17
SQL соединяется с графикой запросов и информации. Различные типы соединений SQL
В некоторых экземплярах может понадобиться исключить отдельные строки из групп (с использованием предложения WHERE) до того, как применять условие к группе как к целому (с использованием предложения HAVING).
Предложение HAVING подобно предложению WHERE, но применимо только к целым группам (то есть к строкам в результирующем наборе, представляющим собой группы), тогда как предложение WHERE применимо к отдельным строкам. В запросе могут содержаться оба предложения: WHERE и HAVING. В этом случае:
Предложение WHERE применяется сначала к отдельным строкам таблиц или возвращающих табличное значение объектов на панели диаграмм. Группируются только строки, которые удовлетворяют условиям в предложении WHERE.
Затем предложение HAVING применяется к строкам в результирующем наборе. Только строки, которые удовлетворяют условиям HAVING, появляются в результирующем запросе. Можно применить предложение HAVING только к тем столбцам, которые появляются в предложении GROUP BY или агрегатной функции.
Например, соединяются таблицы titles и publishers для создания запроса, в котором показана средняя цена книги для группы издателей. Требуется средняя цена книги только определенной группы издателей — например, только издателей в штате Калифорния. При этом нужно показать только те средние цены, которые превышают $10,00.
Первое условие можно задать с помощью предложения WHERE, которое устраняет всех издателей не из Калифорнии перед тем, как начать вычисление средней цены. Второе условие требует предложения HAVING, так как условие основано на результатах группирования и сводных данных. Конечная инструкция SQL может выглядеть следующим образом:
Можно создать оба предложения HAVING и WHERE на панели критериев. По умолчанию любое заданное условие поиска для столбца становится частью предложения HAVING. Однако можно изменить условие, сделав его предложением WHERE.
Можно создать предложение WHERE и HAVING для одного и того же столбца. Для этого необходимо дважды добавить столбец на панели критериев, затем указать один экземпляр как часть предложения HAVING и другой экземпляр как часть предложения WHERE.
Задание условия WHERE в статистическом запросе
Укажите группы для запроса. Дополнительные сведения см. в статье о группировании строк в результатах запроса.
Если столбец, на котором основывается условие WHERE, находится не на панели критериев, то добавьте его на панель критериев.
Очистите столбец Вывод , если столбец данных не является частью предложения GROUP BY или не входит в агрегатную функцию.
В столбце Фильтр укажите условие WHERE. Конструктор запросов и представлений добавляет условие в предложение HAVING инструкции SQL.
В качестве примера данной процедуры показан запрос, соединяющий две таблицы titles и publishers .
В этой точке в запросе инструкции SQL содержится предложение HAVING:
В столбце Группировать выберите Where из списка параметров группировки и сводки. Конструктор запросов и представлений удаляет условие из предложения HAVING инструкции SQL и добавляет его в предложение WHERE.
должно быть, я гуглю не так, или у меня есть глупый момент времени.
в чем разница между HAVING и WHERE на SQL SELECT заявление?
EDIT: я отметил ответ Стивена как правильный, поскольку он содержал ключевой бит информации по ссылке:
, когда GROUP BY не используется, HAVING ведет себя как WHERE п.
ситуация, которую я видел WHERE не было GROUP BY и вот где началось мое замешательство. Конечно, пока вы не знаете этого, вы не можете указать это в вопросе.
большое спасибо за все ответы, которые были очень поучительно.
HAVING задает условие поиска для a группа или агрегатная функция, используемая в инструкции SELECT.
наличие: используется для проверки условий после агрегация происходит.
Где: используется для проверки условий до агрегация происходит.этот код:
дает вам таблицу всех городов в МА и количеству адресов в каждом городе.
этот код:
дает вам таблицу городов в МА с более чем 5-адресов и количество адресов в каждом городе.
- Count()
- Sum()
- avg()
- Min()
- Max()
предложение HAVING было добавлено в SQL, потому что ключевое слово WHERE не могло использоваться с агрегатными функциями.
зацените w3schools ссылке для получения дополнительной информации
синтаксис:
такой запрос:
. может быть переписан с использованием производной таблицы (и опуская HAVING ) такой:
WHERE comes before GROUP BY; SQL оценивает предложение WHERE перед тем, как он группирует записи.
HAVING приходит после GROUP BY; SQL оценивает наличие после него групп записей.
оператор SQLite SELECT Синтаксис / Схема Железной Дороги
Informix SELECT оператор синтаксис / схема железной дороги
HAVING используется, когда вы используете агрегат, такой как GROUP BY .
где применяется в качестве ограничения на набор, возвращаемый SQL; он использует встроенный набор oeprations и индексов SQL и поэтому является самым быстрым способом фильтрации результирующих наборов. Всегда используйте там, где это возможно.
наличие необходимо для некоторых агрегатных фильтров. Он фильтрует запрос после того, как sql извлек, собрал и отсортировал результаты. Таким образом, это гораздо медленнее, чем где и следует избегать, за исключением тех ситуаций, которые требуют этого.
SQL Server позволит вам уйти с помощью имея даже тогда, когда где было бы намного быстрее. Не делай этого.
где предложение не работает для агрегатных функций
значит : вы не должны использовать вот так бонус : имя таблицывот вместо того, чтобы использовать предложение where, вы должны использовать имеющие..
без использования предложения GROUP BY, предложение HAVING просто работает как предложение WHERE
Читайте также: