MySQL Query 中的 HAVING 和 WHERE 有啥区别?

Posted

技术标签:

【中文标题】MySQL Query 中的 HAVING 和 WHERE 有啥区别?【英文标题】:What's the difference between HAVING and WHERE in MySQL Query?MySQL Query 中的 HAVING 和 WHERE 有什么区别? 【发布时间】:2011-11-18 09:15:55 【问题描述】:

我有一个基于某些表连接的视图 (viewX):

当我使用WHERE时,查询延迟,处理器使用率达到50%,最后我需要关闭mysqld.exe服务并重新启动以尝试再次解决问题。

当我使用HAVING 时,查询完美而快速地执行,我得到了结果,一切就绪。

查询类似这样:

SELECT * FROM viewX WHERE column_of_view = 'foo'

SELECT * FROM viewX HAVING column_of_view = 'foo'

发生了什么?

我找到的解决方案是这样做:

SELECT * FROM (SELECT * FROM viewX) as T WHERE column_of_view = 'foo'

SELECT * FROM (SELECT * FROM viewX) as T HAVING column_of_view = 'foo'

两个查询都很好,但是,我认为这很糟糕! (SELECT * FROM (...viewX)????)

【问题讨论】:

你能发布一些执行计划吗? 我最好的猜测是,通过使用 HAVING 你会混淆查询优化器,就像你让我感到困惑一样,并且这种混淆会导致不同的执行计划(不同的连接顺序和方法),在这个case 实际上可能是有益的(对于许多连接,次优连接顺序的可能性是巨大的)。它只是更快地返回前几行,还是所有行的整个选择也更快? 如果同时指定会发生什么? 视图是否已有聚合? 【参考方案1】:

Having 用于 sum、avg 等聚合函数,只能在 select 语句中使用。where 子句在聚合条件下不起作用 例如:其中 sum(mark) > 300 // 不正确

【讨论】:

【参考方案2】:

WHERE 在列出时使用,但还没有可用的 ALIAS 名称

HAVING在列出所有可能的行之后过滤行,以便生成别名

内联过滤行时应该有问题。

【讨论】:

【参考方案3】:

WHERE用于根据条件过滤查询结果。

HAVING 用于对聚合函数的结果应用过滤器。在没有聚合函数的情况下,它的功能与 WHERE 相同。

http://blog.sqlauthority.com/2007/07/04/sql-server-definition-comparison-and-difference-between-having-and-where-clause/

【讨论】:

这是正确的,但没有解释发生了什么。事实上,它认为应该没有区别。【参考方案4】:

这取决于视图的定义 - having 子句应仅适用于聚合查询,并在分组后应用。你看过这两个查询计划(带解释)吗?

【讨论】:

以上是关于MySQL Query 中的 HAVING 和 WHERE 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

正确理解MySQL中的where和having的区别(转载)

group by having用法举例

mysql中的select语句where条件group by ,having , order by,limit的顺序及用法

GROUP BY和HAVING 以及mysql中常用的日期函数

在SQL中的WHERE和HAVING语句中使用别名?

mysql having和using使用