【问题标题】:MySql - HAVING vs WHERE [duplicate]MySql - HAVING vs WHERE [重复]
【发布时间】:2013-04-15 21:01:27
【问题描述】:

这两个查询有什么区别?

SELECT f.name, 
       u.name, 
       u.id 
FROM   families f 
       JOIN units u 
         ON f.unit_id = u.id 
HAVING u.id IN( 43, 413, 22 )

还有:

SELECT f.name, 
       u.name, 
       u.id 
FROM   families f 
       JOIN units u 
         ON f.unit_id = u.id 
WHERE  u.id IN( 43, 413, 22 )

这两个查询的结果是完全一样的。那么区别在哪里呢?

【问题讨论】:

标签: mysql


【解决方案1】:

WHERE用于选择正在处理的原始表中的数据。

HAVING 用于过滤查询生成的结果集中的数据。这意味着它可以在SELECT 子句中引用聚合值和别名。

例如,可以写:

SELECT t1.val - t2.val diff
FROM t1 JOIN t2 ON (some expression)
HAVING diff > 10

这不能使用WHERE,因为diff 是一个别名,而不是原始表列之一。你可以改写:

SELECT t1.val - t2.val diff
FROM t1 JOIN t2 ON (some expression)
WHERE t1.val - t2.val > 10

但它可能必须将所有减法执行两次:一次用于选择,另一次用于生成结果集。

【讨论】:

  • 但是,having 也可以用于与where 一起使用的普通非聚合谓词中。例如。 where 1=1having 1=1。为什么允许这样做?
  • HAVING 只计算结果集中每一行的表达式。如果为真,则将行保留在结果中,否则将其删除。允许任何表达式,唯一的区别是它在别名可用的范围内。
  • 我的意思是,将非聚合比较放在having 中不是没有意义吗?他们不应该放在where吗?
  • WHERE 只能重新引用原表中的列,不能引用SELECT 中的别名。 WHERE 在生成结果集之前进行过滤,HAVING 在之后进行过滤。虽然它通常用于聚合结果,但它可以用于结果集中的任何内容。它实际上只是将原始查询放入子查询中,然后在外部查询中使用WHERE 子句的简写。
  • Ic,所以您是说将非聚合过滤器从 having 转移到 where 可能不会完全返回相同的结果集?
【解决方案2】:

sql中的have子句和where子句的区别在于where子句不能和聚合一起使用,但是have子句可以。一种思考方式是,have 子句是 where 子句的附加过滤器。

哪个更好:click

【讨论】:

  • 很棒的文章和解释。谢谢。
  • 那篇文章非常有帮助,+1
  • 这个链接有效吗?我正在尝试访问,但它显示地址无效。请检查是否只有我出错。
  • 是的,它正在工作。可能是你有一些代理问题
  • 链接对我不起作用。看到 ERR_CONNECTION_TIMED_OUT
【解决方案3】:

在这些查询中,什么都没有。但如果您使用GROUP BY,您会看到不同。如果您要使用GROUP BY,则HAVING 将应用于组,而WHERE 将应用于SELECT,然后再对数据进行分组。

【讨论】:

  • 你能举个例子让我看到这个查询的不同之处吗?
  • 我可以。 SELECT shapeType, count(shapeType) countShapeType from shapes group by shapeType HAVING countShapeType > 10 在此查询中,您选择按形状类型分组的所有形状,并仅显示您拥有超过 10 个的那些类型。您将无法在 where 语句中执行此操作,因为您无法访问计数聚合。
猜你喜欢
  • 2013-11-25
  • 1970-01-01
  • 2016-01-09
  • 1970-01-01
  • 2019-12-09
  • 2011-11-18
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
相关资源
最近更新 更多