这是我在编写SQL查询时通常面临的情况。我认为编写整个列(例如长整数表达式,带有长参数的求和函数)而不是GROUP BY表达式中的别名会使查询更长,更不易读。为什么Oracle SQL不允许我们在GROUP BY子句中使用列别名?必须有一个重要的原因。
答案 0 :(得分:45)
它不仅仅是Oracle SQL,实际上我认为它符合ANSI SQL标准(尽管我没有参考)。原因是SELECT子句在
也许这个有点荒谬的例子有助于澄清问题以及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)