6

如果我在子句中创建别名,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'; 

这行得通。为什么这样?

4

1 回答 1

5

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

编辑基于 Martin Smith 的更正

HAVING创建以允许过滤由GROUP BY. 指定no 时GROUP BY,将整个结果视为一个组。

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

或者

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

编辑 2 现在关于别名:

关于搜索条件中列引用的 WHERE 子句规范说明了这一点:

<column reference>直接包含在 中的每个<search condition>都应明确引用T的列或作为外部引用。

参考:7.6 <where clause>,​​语法规则 1。

关于搜索条件中列引用的 HAVING 子句规范说明了这一点:

<column reference>直接包含在 中的 每个<search condition>都应明确引用T的分组列或作为外部引用。

参考:7.8 <having clause>,语法规则 1。

分组列定义为:

a 中引用的列<group by clause>是分组列。

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

(第二次非正式审查草案)ISO/IEC 9075:1992,数据库语言 SQL - 1992 年 7 月 30 日

于 2012-08-23T14:15:13.457 回答