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的区别(转载)
mysql中的select语句where条件group by ,having , order by,limit的顺序及用法