【问题标题】:difference between where and having with respect to aliases关于别名的位置和拥有之间的区别
【发布时间】:2012-08-24 02:04:54
【问题描述】:

如果我在select 子句中创建别名,那么我不能在where 子句中使用它,因为根据sql 查询的执行顺序,whereselect 之前。

但是我可以在select 子句中创建一个别名,并在having 子句中使用它,尽管havingselect 之前。

为什么会这样?

例如:

select type, (case when number>25 then 1 else 0 end) inc 
from animals
where inc='1';

这行不通。但是,

select type, (case when number>25 then 1 else 0 end) inc 
from animals
having inc='1'; 

这行得通。为什么会这样?

【问题讨论】:

  • 这是标准的 MySQL 扩展。例如,您不能在 SQL Server 中引用 having 中的列别名。

标签: sql group-by having having-clause


【解决方案1】:

基本上是因为它们是为不同目的而定义的。 WHERE 子句用于记录过滤,HAVING 子句用于过滤聚合函数 (GROUP BY)。 在您的第二个查询中,使用了隐式 GROUP BY 过滤,例如,如果您在 SELECT 子句中添加另一列,您最终会得到不同的结果。

编辑基于 Martin Smith 的更正

创建HAVING 是为了允许过滤由GROUP BY 生成的行。如果未指定GROUP BY,则将整个结果视为一个组。

如果既没有指定 <where clause> 也没有指定 <group by clause>, 则令 T 为前面 <from clause> 的结果

...该组是 如果没有指定<group by clause>,则整个表

编辑 2 现在关于 ALIAS:

关于搜索条件中列引用的 WHERE 子句规范是这样说的:

每个&lt;column reference&gt;直接包含在<search condition>中 明确引用 T 的 一列 或作为外部引用。

参考:7.6 &lt;where clause&gt;,语法规则 1。

关于搜索条件中列引用的 HAVING 子句规范是这样说的:

直接包含在<search condition> 中的每个&lt;column reference&gt; 都应明确引用T 的分组列 或成为外部参考。

参考:7.8 &lt;having clause&gt;,语法规则 1。

分组列定义为:

&lt;group by clause&gt; 中引用的列是一个分组列。

因此,总而言之,WHERE 必须引用表的列,HAVING 子句必须引用行组的分组列。

(Second Informal Review Draft) ISO/IEC 9075:1992, Database Language SQL- July 30, 1992

【讨论】:

  • 但是在 'select' 执行之前,'have' 是如何获取别名的呢?
  • 任何引用“在标准 SQL 中,您不能在没有 GROUP BY 的情况下使用 HAVING 子句”?
  • 没有引用,但众所周知,创建 HAVING 是为了过滤由 GROUP BY 子句产生的行。 en.wikipedia.org/wiki/SQL
  • @user1619966 HAVING 在执行选择之前不会选择别名。每次您在大多数数据库中运行 SQL 查询时,数据库引擎都会处理您的 SQL 并创建执行计划,SQL 会进行转换和改进,您在屏幕上看到的并不总是准确的执行。
  • SELECT SUM(number) FROM SomeTable 是完全有效的 SQL。很确定SELECT SUM(number) FROM SomeTable HAVING SUM(number) &gt; 1000 也是,你的最后一行不正确。请随时将我指向the relevant part of the specification,您认为这是被禁止的。我所看到的只是&lt;table expression&gt; ::= &lt;from clause&gt; [ &lt;where clause&gt; ][ &lt;group by clause&gt; ][ &lt;having clause&gt; ],表明这三者的任何排列都可以。
猜你喜欢
  • 1970-01-01
  • 2013-10-30
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
  • 2011-03-13
  • 2013-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多