为什么Oracle SQL不允许我们在GROUP BY子句中使用列别名?

时间:2010-04-21 09:01:16

标签: sql oracle group-by alias

这是我在编写SQL查询时通常面临的情况。我认为编写整个列(例如长整数表达式,带有长参数的求和函数)而不是GROUP BY表达式中的别名会使查询更长,更不易读。为什么Oracle SQL不允许我们在GROUP BY子句中使用列别名?必须有一个重要的原因。

5 个答案:

答案 0 :(得分:45)

它不仅仅是Oracle SQL,实际上我认为它符合ANSI SQL标准(尽管我没有参考)。原因是SELECT子句在子句之后进行逻辑处理,因此在完成GROUP BY时,别名尚不存在。

也许这个有点荒谬的例子有助于澄清问题以及SQL避免的歧义:

SQL> select job as sal, sum(sal) as job
  2  from scott.emp
  3  group by job;

SAL              JOB
--------- ----------
ANALYST         6000
CLERK           4150
MANAGER         8275
PRESIDENT       5000
SALESMAN        5600

答案 1 :(得分:13)

我知道这是一个旧线程,但似乎用户问题并没有真正解决;这些解释很好地解释了为什么group by子句不允许你使用别名,但没有给出替代方案。

根据上面的信息,在select子句的别名存储在内存中之前,不能在组中使用别名,因为group by先运行。因此,对我的观点起作用的简单解决方案是添加一个外部选择,它只选择别名,然后在同一级别进行分组。

示例:

SELECT alias1, alias2, alias3, aliasN
FROM
(SELECT field1 as alias1, field2 as alias2, field3 as alias3, fieldN as aliasN
 FROM tableName
 WHERE ' ' = ' ')
GROUP BY alias1, alias2, alias3, aliasN

一旦你看到了解决方案,那就非常直接了,但是如果你第一次尝试自己弄清楚,那就是PITA。

这是我能够从case语句“分组”派生字段的唯一方法,所以这是一个很好的技巧。

答案 2 :(得分:3)

虽然我同意在GROUP BY子句中引用带别名的表达式会有所帮助,但我猜测它是不可能的,因为GROUP BY子句在 SELECT子句之前被评估。

这也可以解释为什么你可以在ORDER BY子句中使用列别名(i-e:最后评估ORDER BY子句)。

答案 3 :(得分:2)

虽然这似乎是一个合乎逻辑的答案,但事实上它是一个非常用户不友好的答案。 在处理查询之前,Oracle会读取它,通过读取它,预处理器可以用原始语句替换别名,并仍然将正确的查询发送到数据库。 与您可以按1,2,3编码顺序相同,您还应该能够按1,2,3或别名进行分组。

答案 4 :(得分:1)

但有些RDBMS可以,这适用于PostgreSQL:

select emp.lastname || ' ' || emp.firstname as fullname, count(emp_work.*) as cnt
from emp
left join emp_work using(emp_id)
group by fullname

这将有效,只要分组的别名不是聚合函数的结果,group by cnt将无法正常工作

但是我可能会猜测group by fullname被扩展为group by emp.lastname || ' ' || emp.firstname as fullname,而SELECT子句只是选择该分组的全名结果;虽然在语法上看起来相反。 GROUP总是先执行,然后执行最后一次(即SELECT)