哪里与有

发布于 2024-09-02 16:55:27 字数 176 浏览 5 评论 0原文

在 MySQL 中,为什么需要将您自己创建的列(例如 select 1 as "number")放置在 HAVING 之后,而不是 WHERE

与执行 WHERE 1 (编写整个定义而不是列名)相比,有什么缺点吗?

Why do you need to place columns you create yourself (for example select 1 as "number") after HAVING and not WHERE in MySQL?

And are there any downsides instead of doing WHERE 1 (writing the whole definition instead of a column name)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

囚你心 2024-09-09 16:55:27

其他关于这个问题的回答都没有说到重点。

假设我们有一个表:

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;

上面的查询将引发错误:Error #1054 - Unknown column 'v' in 'where Clause'

SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows

WHERE 子句允许条件使用任何表列,但不能使用别名或聚合功能。
HAVING 子句允许条件使用选定的 (!) 列、别名或聚合函数。

这是因为WHERE子句在select之前过滤数据,而HAVING子句在select之后过滤结果数据。

所以将条件放在WHERE<如果表中有很多行,/code> 子句会更有效。

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

您可以看到 WHEREHAVING 使用索引,但行不同。

All other answers on this question didn't hit upon the key point.

Assume we have a table:

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

And have 10 rows with both id and value from 1 to 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);

Try the following 2 queries:

SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows
SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows

You will get exactly the same results, you can see the HAVING clause can work without GROUP BY clause.


Here's the difference:

SELECT `value` v FROM `table` WHERE `v`>5;

The above query will raise error: Error #1054 - Unknown column 'v' in 'where clause'

SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows

WHERE clause allows a condition to use any table column, but it cannot use aliases or aggregate functions.
HAVING clause allows a condition to use a selected (!) column, alias or an aggregate function.

This is because WHERE clause filters data before select, but HAVING clause filters resulting data after select.

So put the conditions in WHERE clause will be more efficient if you have many many rows in a table.

Try EXPLAIN to see the key difference:

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

You can see either WHERE or HAVING uses index, but the rows are different.

感受沵的脚步 2024-09-09 16:55:27

为什么您需要将自己创建的列(例如“选择 1 作为数字”)放置在 MySQL 中的 HAVING 之后而不是 WHERE 之后?

WHEREGROUP BY 之前应用,HAVING 在之后应用(并且可以对聚合进行过滤)。

一般来说,您不能在这些子句中引用别名,但 MySQL 允许在 GROUP BY、ORDER BY 中引用 SELECT 级别别名 和拥有

与执行“WHERE 1”(编写整个定义而不是列名称)相比,是否有任何缺点

如果您的计算表达式不包含任何聚合,则将其放入 WHERE 子句很可能是更有效率。

Why is it that you need to place columns you create yourself (for example "select 1 as number") after HAVING and not WHERE in MySQL?

WHERE is applied before GROUP BY, HAVING is applied after (and can filter on aggregates).

In general, you can reference aliases in neither of these clauses, but MySQL allows referencing SELECT level aliases in GROUP BY, ORDER BY and HAVING.

And are there any downsides instead of doing "WHERE 1" (writing the whole definition instead of a column name)

If your calculated expression does not contain any aggregates, putting it into the WHERE clause will most probably be more efficient.

っ左 2024-09-09 16:55:27

主要区别在于 WHERE 不能用于分组项(例如 SUM(number)),而 HAVING 可以。

原因是 WHERE 是在分组之前完成的,而HAVING是在分组之后完成的。

The main difference is that WHERE cannot be used on grouped item (such as SUM(number)) whereas HAVING can.

The reason is the WHERE is done before the grouping and HAVING is done after the grouping is done.

从﹋此江山别 2024-09-09 16:55:27

HAVING 用于过滤 GROUP BY 中的聚合。

例如,要检查重复的名称:

SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1

HAVING is used to filter on aggregations in your GROUP BY.

For example, to check for duplicate names:

SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
初见终念 2024-09-09 16:55:27

这两个感觉与第一个相同,因为两者都用于说明过滤数据的条件。尽管在任何情况下我们都可以使用“having”代替“where”,但在某些情况下我们不能使用“where”代替“having”。这是因为在选择查询中,“where”过滤“select”之前的数据,而“having”过滤“select”之后的数据。因此,当我们使用实际上不在数据库中的别名时,“where”无法识别它们,但“having”可以。

例如:让表 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.*/

These 2 will be feel same as first as both are used to say about a condition to filter data. Though we can use ‘having’ in place of ‘where’ in any case, there are instances when we can’t use ‘where’ instead of ‘having’. This is because in a select query, ‘where’ filters data before ‘select’ while ‘having’ filter data after ‘select’. So, when we use alias names that are not actually in the database, ‘where’ can’t identify them but ‘having’ can.

Ex: let the table Student contain student_id,name, birthday,address.Assume birthday is of type 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.*/
橘寄 2024-09-09 16:55:27

WHERE 在数据分组之前进行过滤,HAVING 在数据分组之后进行过滤。这是一个重要的区别;行是
WHERE 子句消除的内容将不会包含在该组中。这
可能会改变计算值,这反过来(=作为结果)可能会影响哪个
根据HAVING中这些值的使用来过滤组
条款。

并继续,

HAVINGWHERE 非常相似,以至于大多数 DBMS 将它们视为相同
如果没有指定GROUP BY,就会发生这种情况。尽管如此,你应该这样做
自己的区别。 HAVING 仅与 GROUP BY 结合使用
条款。使用WHERE进行标准行级过滤。

摘录自:
福塔,本。 “Sams 在 10 分钟内自学 SQL(第 5
版)(萨姆斯自学...)。”。

WHERE filters before data is grouped, and HAVING filters after data is grouped. This is an important distinction; rows that are
eliminated by a WHERE clause will not be included in the group. This
could change the calculated values which, in turn(=as a result) could affect which
groups are filtered based on the use of those values in the HAVING
clause.

And continues,

HAVING is so similar to WHERE that most DBMSs treat them as the same
thing if no GROUP BY is specified. Nevertheless, you should make that
distinction yourself. Use HAVING only in conjunction with GROUP BY
clauses. Use WHERE for standard row-level filtering.

Excerpt From:
Forta, Ben. “Sams Teach Yourself SQL in 10 Minutes (5th
Edition) (Sams Teach Yourself...).”.

梦萦几度 2024-09-09 16:55:27

having 仅与聚合一起使用,但 where 与非聚合语句一起使用
如果你有where word把它放在聚合之前(group by)

Having is only used with aggregation but where with non aggregation statements
If you have where word put it before aggregation (group by)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文