bal*_*loo 241 mysql sql where-clause having-clause
为什么你需要把你自己创建的(例如列select 1 as "number"
后)HAVING
,而不是WHERE
在MySQL?
是否有任何缺点而不是做WHERE 1
(编写整个定义而不是列名)?
Qua*_*noi 315
为什么你需要在HAVING之后放置你自己创建的列(例如"select 1 as number")而不是MySQL中的WHERE?
WHERE
被施加之前GROUP BY
,HAVING
被后应用(并且可以在聚集体筛选).
在一般情况下,你可以在没有这些条款的引用别名,但MySQL
可以参考SELECT
水平别名GROUP BY
,ORDER BY
和HAVING
.
是否有任何缺点而不是做"WHERE 1"(写整个定义而不是列名)
如果计算的表达式不包含任何聚合,则将其放入WHERE
子句中可能会更有效.
Fis*_*ned 275
所有的答案都没有达到关键点.
假设我们有一张桌子:
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
Run Code Online (Sandbox Code Playgroud)
并且有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);
Run Code Online (Sandbox Code Playgroud)
尝试以下2个查询:
SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows
SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows
Run Code Online (Sandbox Code Playgroud)
您将获得完全相同的结果,您可以看到HAVING子句可以在没有GROUP BY子句的情况下工作.
这是区别:
SELECT `value` v FROM `table` WHERE `v`>5;
Run Code Online (Sandbox Code Playgroud)
错误#1054 - 'where子句'中的未知列'v'
SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows
Run Code Online (Sandbox Code Playgroud)
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 |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
Run Code Online (Sandbox Code Playgroud)
您可以看到WHERE或HAVING使用索引,但行不同.
Kev*_*vin 39
HAVING
用于过滤您的聚合GROUP BY
.
例如,要检查重复的名称:
SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
Run Code Online (Sandbox Code Playgroud)
小智 7
这两个将与第一个相同,因为两者都用于说明过滤数据的条件.虽然我们可以在任何情况下使用'have'来代替'where',但有些情况下我们不能使用'where'而不是'having'.这是因为在选择查询中,"where"在'select'之前过滤数据,而在'select'之后'过滤'数据.因此,当我们使用实际上不在数据库中的别名时,"where"无法识别它们,但"有"可以.
例如:让学生表包含student_id,姓名,生日,地址.假设生日是日期类型.
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.*/
Run Code Online (Sandbox Code Playgroud)