Hive学习笔记 为什么group by不能使用别名?

Posted 赤兔在云端

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive学习笔记 为什么group by不能使用别名?相关的知识,希望对你有一定的参考价值。

赤兔 | 学习笔记

注意SQL语句的执行顺序


问题来自于类似如下的场景:数据库中的每行代表一个用户的购买记录,每列是用户和购买的属性,例如性别、购买时间等,其中的一个字段代表的是消费者购买金额。现在要求按照消费金额分档,并统计各档位的消费者数量。比如我们按0元-500元、500元-1000元和1000元+将用户分成三组,并统计出各组的用户数量。


错误的方法当我遇到这个问题,首先想到的是生成一个新列,并按新列分组。方法是使用case when语句将用户分组,然后给这列起一个别名,比如就叫classifying好了,再用group by classifying,就可以统计出各组的用户数量了。但是当执行的时候,会报语句错误:classifying这列不存在。


给查询的列起别名是很常用的方法,为什么这里却不行了呢?

1.可能group by不支持新生成的列的别名

2.可能group by后面就是不能使用别名


为了验证可能的原因,我用数据库原有的字段进行分组尝试,结果一旦使用了别名就会报错,而用原有列名则能正常查询。这就很奇怪了,为什么order by可以使用别名,但是group by不可以呢?按照人的习惯,使用别名更加方便才对,为什么不这样设计呢?


反复思索后,我突然想到:select后面的列其实是查询结果,而group by是查询的条件,order by是基于结果之后的排序,有没有可能程序是按照一定的顺序执行SQL语句的呢?如果是这样,where后面应该也不能使用别名,通过试验果真如此。在网上搜索了一些问题之后,终于找到了满意的解释,一般来说,查询的执行顺序是:

不同的数据库,还会有其它语句的优先级需要考虑,比如START WITH、CONNECT BY等,因为在hive中用不到就没有进一步研究了。


回到最初的问题,既然无法使用别名,那么如何按照我们设想的方式分组呢?答案是只能麻烦一些,把我们查询的case when语句放到group by后面,例如:

Hive学习笔记(一) 为什么group by不能使用别名?

group by这样使用,让我想起曾在课堂上见过的一道面试题:

这里其实就是group by后面需要添加条件的情况,参考答案如下(经本人测试有些小问题):

(小问题是,select后面的case when需要和group by的条件保持一致,本例中group by用<9000和<20进行分组,那么需要在select里先写salary<9000以及age<20的条件,否则会报错。即 case when salary<9000 then '薪资小于9000' else '薪资大于9000' end as '薪资')


这里可以发现group by的有意思之处,group by不仅可以按照原有字段分组,还可以根据新的条件分组,只不过在二分组的情况下语句简单,而多分组的语句要复杂一些。二分组其实也是比较有用的,比如有的时候可以结合LEFT JOIN和<some_list> IS NULL来进行分组,就不用写更多的case when语句了(外连接后关键字段会产生空值,巧妙的利用可以解决一些本来复杂的查询问题)。


此外,需要注意的是,使用group by后,select的字段必须是出现在group by之后的字段,或者使用聚合函数,这个过程可以使用excel的数据透视表来理解。简单说就是,想要显示未经分组的字段记录,是不符合逻辑的(比如按年龄分组却要显示性别是不行的,必须把性别也加到分组条件中)。


总结一下:

1.SQL语句的执行是有先后顺序的,因此大部分数据库,WHERE和GROUP BY后面不能使用别名,但是ORDER BY可以使用别名。


2.GROUP BY后面的列,可以是复杂的分组判断,用CASE WHEN语句实现;但如果是二分组问题就比较简单,只写一个条件即可,不过要注意和SELECT的条件一致。


3.使用GROUP BY,SELECT后面的字段必须是GROUP BY后的字段或者聚合函数,不能查询在GROUP BY后面未出现的列。

以上是关于Hive学习笔记 为什么group by不能使用别名?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 hive 中执行 group by 时出现错误?

hive distribute by 和group by 的区别

SQL (Hive):在使用 GROUP BY 进行聚合时使用窗口函数

在 HIVE 中使用 DISTINCT 和 GROUP BY

Hive SQL子句中 group by 1 是什么意思?

Hive SQL子句中 group by 1 是什么意思?