ГДЕ против

Зачем вам нужно размещать столбцы, которые вы создаете сами (например, select 1 as "number") после HAVING и не WHERE в MySQL?

И есть ли минусы вместо того, чтобы делать WHERE 1 (писать полное определение вместо названия столбца)?

7 ответов

Решение

Почему вам нужно разместить столбцы, которые вы создаете сами (например, "выберите 1 как число") после HAVING, а не WHERE в MySQL?

WHERE применяется раньше GROUP BY, HAVING применяется после (и может фильтровать по агрегатам).

В общем, вы можете ссылаться на псевдонимы ни в одном из этих пунктов, но MySQL позволяет ссылаться SELECT псевдонимы уровня в GROUP BY, ORDER BY а также HAVING,

И есть ли недостатки, вместо того, чтобы делать "ГДЕ 1" (писать полное определение вместо имени столбца)

Если ваше вычисленное выражение не содержит агрегатов, поместите его в WHERE пункт, скорее всего, будет более эффективным.

Все ответы не достигли ключевой точки.

Предположим, у нас есть таблица:

CREATE TABLE `table` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `value` int(10) unsigned NOT NULL,
 PRIMARY KEY (`id`),
 KEY `value` (`value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

И иметь 10 строк с идентификатором и значением от 1 до 10:

INSERT INTO `table`(`id`, `value`) VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5),(6, 6),(7, 7),(8, 8),(9, 9),(10, 10);

Попробуйте следующие 2 запроса:

SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows
SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows

Вы получите точно такие же результаты, вы можете видеть, что предложение HAVING может работать без предложения GROUP BY.

Вот разница:

SELECT `value` v FROM `table` WHERE `v`>5;

Ошибка № 1054 - Неизвестный столбец "v" в "предложении где"

SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows

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

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

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

Попробуйте EXPLAIN, чтобы увидеть ключевое отличие:

EXPLAIN SELECT `value` v FROM `table` WHERE `value`>5;
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key   | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
|  1 | SIMPLE      | table | range | value         | value | 4       | NULL |    5 | Using where; Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+

EXPLAIN SELECT `value` v FROM `table` having `value`>5;
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key   | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
|  1 | SIMPLE      | table | index | NULL          | value | 4       | NULL |   10 | Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+

Вы можете видеть, ГДЕ или ХЭВИНГ использует индекс, но строки разные.

Основное отличие состоит в том, что WHERE нельзя использовать для сгруппированного элемента (например, SUM(number)) в то время как HAVING Можно.

Причина в том, что WHERE делается до группировки и HAVING делается после того, как группировка завершена.

HAVING используется для фильтрации по агрегатам в вашем GROUP BY,

Например, чтобы проверить дубликаты имен:

SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1

Эти 2 будут восприниматься так же, как и первые, поскольку оба используются, чтобы сказать об условии фильтрации данных. Хотя мы можем использовать "иметь" вместо "где" в любом случае, бывают случаи, когда мы не можем использовать "где" вместо "иметь". Это связано с тем, что в запросе выбора "где" фильтрует данные до "выбора", а "фильтрует данные после" выбора ". Таким образом, когда мы используем псевдонимы, которых на самом деле нет в базе данных, "где" не может их идентифицировать, но "иметь" может.

Пример: пусть таблица Student содержит идентификатор student_id, имя, день рождения, адрес. Предположим, день рождения имеет тип date.

SELECT * FROM Student WHERE YEAR(birthday)>1993; /*this will work as birthday is in database.if we use having in place of where too this will work*/

SELECT student_id,(YEAR(CurDate())-YEAR(birthday)) AS Age FROM Student HAVING Age>20; 
/*this will not work if we use ‘where’ here, ‘where’ don’t know about age as age is defined in select part.*/

WHERE фильтрует данные перед группировкой, а HAVING - после группировки данных. Это важное различие; строки, которые исключены предложением WHERE, не будут включены в группу. Это может изменить вычисленные значения, что, в свою очередь, может повлиять на то, какие группы фильтруются на основе использования этих значений в предложении HAVING.

Отрывок из: Форта, Бен. "Самс научит себя SQL за 10 минут (4-е издание) (Самс учит себя...)".

Наличие используется только с агрегацией, но там, где не с агрегацией операторов Если у вас есть, где слово положить его перед агрегацией

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

    ВЫБЕРИТЕ SalesOrderID, SUM(UnitPrice * OrderQty) AS TotalPrice ОТ Sales.SalesOrderDetail WHERE LineTotal > 100 ГРУППЫ BY SalesOrderID ИМЕЮТ СУММУ (UnitPrice * OrderQty) > 10000

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

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

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