2012-08-23 60 views
6

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

但我可以创建select子句中的别名,虽然havingselect使用它之前在having条款。

这是为什么?

例:

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'; 

This works。为什么这样?

+6

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

回答

5

基本上,因为他们在哪里定义为不同的目的。 WHERE子句用于记录过滤,HAVING子句设计用于使用集合函数GROUP BY)进行过滤。 在您的第二个查询中,正在使用隐含的GROUP BY筛选,因此,例如,如果向SELECT子句添加另一列,则最终会得到不同的结果。

EDIT由马丁·史密斯

HAVING基于校正是创建允许产生的GROUP BY的行的过滤。当没有指定GROUP BY时,整个结果被视为一个组。

如果既未<where clause>也不是<group by clause>被指定,然后 设T是前述<from clause>

...的组是 整个表的结果如果没有指定<group by clause>

EDIT 2 现在关于别名:

有关将在搜索条件的列的引用在WHERE子句中的规范是:

直接包含在<search condition>每个<column reference>应 明确引用T的列或者是外部参考。

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

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

直接包含在<search condition>每个<column reference>应明确地引用Ť 的分组列或者可以是外参考。

参见:7.8 <having clause>,语法规则1.

而一个分组列被定义为:

<group by clause>引用的列是一个分组列。

所以在最后的WHERE必须引用表中的一列和HAVING子句必须引用组行的一个分组列。

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

+0

但是,在'select'执行之前,'has'是否会提取别名? – pooja

+0

任何引用“在标准SQL中不能使用没有GROUP BY的HAVING子句”? –

+0

没有引用,但众所周知,HAVING是为过滤由GROUP BY子句产生的行而创建的。 http://en.wikipedia.org/wiki/SQL – davidmontoyago

相关问题