ГДЕ против - PullRequest
       48

ГДЕ против

235 голосов
/ 25 мая 2010

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

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

Ответы [ 7 ]

307 голосов
/ 25 мая 2010

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

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

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

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

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

263 голосов
/ 10 сентября 2013

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

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

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' в 'предложении where'

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 |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+

Вы можете видеть, ГДЕ или HAVING использует индекс, но строки отличаются.

61 голосов
/ 25 мая 2010

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

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

39 голосов
/ 25 мая 2010

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

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

SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
7 голосов
/ 21 июня 2015

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

Пример: пусть таблица 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.*/
2 голосов
/ 05 января 2018

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

Выдержка из: Форта, Бен. Самс научит себя SQL за 10 минут Редакция) (Самс учит себя ...). ».

1 голос
/ 09 ноября 2015

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

...