如果我在select
子句中创建别名,那么我就不能在where
子句中使用它,因为根据执行sql查询的顺序where
来自select
}。
但是我可以在select
子句中创建一个别名,并在having
子句中使用它,尽管having
来自select
。
为什么会这样?
例如:
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';
这很有效。为什么这样?
答案 0 :(得分:5)
基本上因为它们定义的目的不同。 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子句的规范说明了这一点:
<column reference>
中直接包含的每个<search condition>
都应该 明确地引用T的列或者是外部引用。
请参阅:7.6 <where clause>
,语法规则1。
关于搜索条件中列引用的HAVING子句的规范说明了这一点:
<column reference>
中直接包含的每个<search condition>
都应明确引用T的分组列 或者是外部参考。
请参阅:7.8 <having clause>
,语法规则1.
分组列定义为:
<group by clause>
中引用的列是分组列。
总之,WHERE
必须引用表的一列,HAVING
子句必须引用该行组的分组列。
(Second Informal Review Draft) ISO/IEC 9075:1992, Database Language SQL- July 30, 1992