在哪里与HAVING
为什么你需要把你自己创build的列(例如select 1 as "number"
)后,而不是在MySQL的WHERE
?
是否有任何缺点,而不是做WHERE 1
(写整个定义,而不是列名)?
为什么你需要在HAVING之后放置你自己创build的列(例如“select 1 as number”),而不是MySQL中的WHERE?
WHERE
在GROUP BY
之前应用, HAVING
在应用之后(并且可以在集合上过滤)。
一般来说,你可以在这两个子句中都引用别名,但MySQL
允许在GROUP BY
, ORDER BY
和HAVING
引用SELECT
级别别名。
是否有任何缺点,而不是做“WHERE 1”(写整个定义,而不是列名)
如果您的计算expression式不包含任何聚合,则将其放入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行,两个ID和值从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 – 'where子句'中的未知列'v'
SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows
WHERE子句要求条件是表中的列,但HAVING子句可以使用列或别名。
这是因为WHERE子句在select之前过滤数据,而HAVING子句在select之后过滤数据。
所以如果你在表中有许多行,那么把条件放在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或HAVING使用索引,但行是不同的。
主要区别在于WHERE
不能用于分组项(如SUM(number)
),而HAVING
可以。
原因是分组完成之前完成了WHERE
,分组完成之后完成了HAVING
。
HAVING
用于过滤GROUP BY
聚合。
例如,要检查重复的名称:
SELECT Name FROM Usernames GROUP BY Name HAVING COUNT(*) > 1
这两个将会和第一个一样,因为两者都被用来说明一个条件来过滤数据。 尽pipe在任何情况下我们都可以用“有”代替“在哪里”,但有些情况下我们不能使用“where”而不是“having”。 这是因为在select查询中,'where'在'select'之前过滤数据,'select'之后'having'过滤数据。 所以,当我们使用实际上不在数据库中的别名时,'where'不能识别它们,而'having'可以。
例如:让表Student包含student_id,姓名,生日,地址。假设生日是typesdate。
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.*/
仅用于聚合,但用于非聚合语句的位置如果您在聚合之前已经将其放在了某个位置(group by)
- WHERE子句用于从结果中筛选logging。 filter发生在任何分组之前。
-
HAVING子句用于过滤来自组的值。 在我们继续之前,让我们回顾一下SQL语句的格式。 它是
SELECT SalesOrderID,SUM(UnitPrice * OrderQty)AS TotalPrice FROM Sales.SalesOrderDetail WHERE LineTotal> 100 GROUP BY SalesOrderID HAVING SUM(UnitPrice * OrderQty)> 10000
关键点,这也是SQL中WHERE和HAVING子句的主要区别在于,WHERE子句中指定的条件在从表中获取数据(行)时使用,未通过条件的数据将不会被获取到结果中另一方面,HAVING子句稍后用于过滤汇总数据或分组数据。
简而言之,如果WHERE和HAVING子句在具有集合函数或GROUP BY子句的SELECT查询中使用,则它将在HAVING子句之前执行。