SQL按照如下顺序执行查询:
FROM子句
WHERE子句
GROUP BY子句
HAVING子句
SELECT子句
ORDER BY子句
对于大多数关系数据库系统来说,这个顺序解释了哪些名称(列或别名)是有效的,因为它们必须在前面的步骤中引入。
因此,在Oracle和SQL Server中,不能在SELECT子句中定义的GROUP BY子句中使用一个术语,因为GROUP BY是在SELECT子句之前执行的。
但是有一些例外情况:MySQL和Postgres似乎有更多的智能。
你总是可以使用子查询,所以你可以使用别名; 当然,检查性能(可能的数据库服务器将运行两个相同的,但从来没有伤害validation):
SELECT ItemName, FirstLetter, COUNT(ItemName) FROM ( SELECT ItemName, SUBSTRING(ItemName, 1, 1) AS FirstLetter FROM table1 ) ItemNames GROUP BY ItemName, FirstLetter
至less在PostgreSQL中,您可以在GROUP BY子句的结果集中使用列号:
SELECT itemName as ItemName, substring(itemName, 1,1) as FirstLetter, Count(itemName) FROM table1 GROUP BY 1, 2
当然,如果你正在交互地进行这个操作,那么开始会很痛苦,并且编辑这个查询来改变结果中列的数量或顺序。 但仍然。
由于处理的逻辑顺序,SQL Server不允许您引用GROUP BY子句中的别名。 GROUP BY子句在SELECT子句之前处理,所以在评估GROUP BY子句时不知道别名。 这也解释了为什么你可以在ORDER BY子句中使用别名。
以下是有关SQL Server逻辑处理阶段的信息的来源。
注意,在Group By中使用别名(对于支持它的服务,如postgres)可能会有意外的结果。 例如,如果您创build内部语句中已存在的别名,则分组依据将select内部字段名称。
-- Working example in postgres select col1 as col1_1, avg(col3) as col2_1 from (select gender as col1, maritalstatus as col2, yearlyincome as col3 from customer) as layer_1 group by col1_1; -- Failing example in postgres select col2 as col1, avg(col3) from (select gender as col1, maritalstatus as col2, yearlyincome as col3 from customer) as layer_1 group by col1;

一些DBMS会让你使用别名,而不必重复整个expression式。

Teradata就是这样一个例子。

根据这个SO问题中logging的原因,我避免了Bill所build议的序号表示法。

简单而强大的替代方法是始终在GROUP BY子句中重复expression式。

DRY不适用于SQL。

在SQLite中将视图结果分组时,请小心使用别名。 如果别名与任何基础表(对视图)的列名相同,您将得到意外的结果。

早在那一天,我发现现在由Oracle支持的前DEC产品Rdb允许在GROUP BY中使用列别名。 通过版本11的主streamOracle不允许在GROUP BY中使用列别名。 不知道Postgresql,SQL Server,MySQL等将会或不会允许。 因人而异。

我不回答为什么是这样,但只是想通过使用CROSS APPLY创build别名来显示在SQL Server中的这种限制的方法。 然后在GROUP BY子句中使用它,如下所示:

SELECT itemName as ItemName, FirstLetter, Count(itemName) FROM table1 CROSS APPLY (SELECT substring(itemName, 1,1) as FirstLetter) Alias GROUP BY itemName, FirstLetter