Ответы:
Почему вам нужно разместить столбцы, которые вы создаете сами (например, «выберите 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 |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
Вы можете видеть, ГДЕ или ХЭВИНГ использует индекс, но строки разные.
SELECT value, COUNT(*) frequency FROM table GROUP BY value HAVING frequency > 10
...HAVING clause can use both column and alias.
на ...HAVING clause can use either column or alias.
и изменение ...WHERE clause will be more effective
на...WHERE clause will be more efficient
Основное отличие состоит в том, что WHERE
нельзя использовать сгруппированный элемент (например, SUM(number)
), тогда как HAVING
можно.
Причина в том, WHERE
делается перед тем группирования и HAVING
делается после того, как группировка делается.
HAVING
используется для фильтрации по агрегатам в вашем GROUP BY
.
Например, чтобы проверить дубликаты имен:
SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
Эти 2 будут восприниматься так же, как и первые, поскольку оба используются для обозначения условия фильтрации данных. Хотя в любом случае мы можем использовать «иметь» вместо «где», бывают случаи, когда мы не можем использовать «где» вместо «иметь». Это связано с тем, что в запросе выбора «где» фильтрует данные до «выбора», а «фильтрует данные после« выбора ». Таким образом, когда мы используем псевдонимы, которых на самом деле нет в базе данных, «где» не может их идентифицировать, но «иметь» может.
Пример: пусть таблица Student содержит идентификатор студента, имя, день рождения, адрес. Предположим, день рождения имеет тип 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 - после группировки данных. Это важное различие; строки, которые исключены предложением WHERE , не будут включены в группу. Это может изменить вычисленные значения, что, в свою очередь (= как результат), может повлиять на то, какие группы фильтруются на основе использования этих значений в предложении HAVING .
И продолжает,
HAVING настолько похож на WHERE, что большинство СУБД рассматривают их как одно и то же, если не указан параметр GROUP BY . Тем не менее, вы должны сделать это различие самостоятельно. Используйте HAVING только в сочетании с предложениями GROUP BY . Используйте WHERE для стандартной фильтрации на уровне строк.
Отрывок из: Форта, Бен. «Самс научит себя SQL за 10 минут (5-е издание) (Самс учит себя ...)».
Наличие используется только с агрегацией, но где с неагрегированными операторами. Если у вас есть, где слово помещается перед агрегацией (сгруппировать по)