ГДЕ против
Зачем вам нужно размещать столбцы, которые вы создаете сами (например, 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.