我知道这被讨论了很多,但我的研究都无法让我相信 MySQL 中 ' where
' 和 ' having
' 子句之间的区别。据我了解,我们可以使用 ' ' 实现使用 'where' 子句可以完成的一切having
。例如。select * from users having username='admin'
. 那你为什么需要' where
'子句?使用 where 会产生任何性能差异吗?
4 回答
WHERE
子句在聚合之前过滤来自源的数据,而子句HAVING
在GROUP BY
应用之后过滤数据。通常这意味着任何非聚合过滤器都可以出现在任一位置,但如果您的查询中未引用列,则只能在WHERE
子句中对其进行过滤。
例如,如果您有下表:
| ID | VALUE |
--------------
| 1 | 15 |
| 2 | 15 |
| 3 | 20 |
| 4 | 20 |
| 5 | 25 |
| 6 | 30 |
| 7 | 40 |
假设您想应用以下查询:
select value, count(value)
from Table1
group by value
但是您只想包含行 where ID > 2
。如果你把它放在一个HAVING
子句中,你会得到一个错误,因为该ID
列在聚合后不可用,因为它不在SELECT
子句中。在这种情况下,您将需要使用一个WHERE
子句:
select value, count(value)
from Table1
where id > 2
group by value
HAVING
fromWHERE
子句之间的区别在于HAVING
支持聚合列,WHERE
而不支持聚合列,因为它仅适用于单个行。,EG
SELECT ID
FROM tableName
GROUP BY ID
HAVING COUNT(ID) > 1 --- <<== HERE
从 MySQL 文档中,
“如果您使用 HAVING 而不是 WHERE,则可以使用别名,这是两个子句之间定义的差异之一。Having 也较慢并且不会被优化,但是如果您将这样的复杂函数放置在您显然在的地方没想到速度很快。”
Where 在单行级别上求值,而 have 用于 group by 表达式。
使用该HAVING
子句,您可以指定过滤组的条件,而不是过滤单个
行,这发生在WHERE
阶段。
只有HAVING
子句中的逻辑表达式计算结果为 TRUE 的组才会由HAVING
阶段返回。逻辑表达式计算结果的组FALSE or UNKNOWN
被过滤掉。
GROUP BY
未使用时,其HAVING
行为类似于WHERE
子句。关于性能比较请看这篇文章