为什么Hive中的group by后面不能使用字段别名?
为什么Hive中的group by后面不能使用字段别名呢?看了这篇文章你将一目了然。
1. 案例说明
我们以一个例子来说明。
(1)数据
创建business.txt,内容如下:
1 | jack,2017-01-01,10 |
(2)创建表
1 | create table business( |
(3)导入数据
1 | load data local inpath "data/business.txt" into table |
(4)查找每月购物的人次
使用字段别名报错:
1 | select substring(orderdate,1,length(orderdate)-3) month_value, count(name) |
报错如下:
1 | FAILED: SemanticException [Error 10004]: Line 3:9 Invalid table alias or column reference 'month_value': (possible column names are: name, orderdate, cost) |
不使用字段别名可以正常运行:
1 | select substring(orderdate,1,length(orderdate)-3) month_value, count(name) |
查询结果为:
1 | month_value _c1 |
2. 分析原因
为了什么使用别名会报错呢?因为Sql语句执行顺序为:
1 | (7) SELECT |
从上述sql的执行顺序可以看出,Group by之所以不能使用字段别名,是因为当执行到第五步GROUP BY
时,第七步的SELECT
还没有执行。由于ORDER BY
在SELECT
后面,所以可以使用字段别名。
另外,FROM
语句是第一步执行的,故所有的关键字都可以使用表别名,这个一定要注意。
3. 解决办法
我们可以通过子查询的方式解决group by
语句不能使用别名的问题,例如查找每月购物的人次,可以通过下列sql语句:
1 | select |
由于最先执行的是最外层from后面的语句,所以group by
可以使用子查询里面的字段别名。
4. 执行效率
分析下列sql
1 | ### 第一个sql |
我们可以看到,下列sql语句有两个substring(orderdate,1,length(orderdate)-3)
,这是不是代表该语句中的方法执行了两次呢?其实并不是,Hive里面经过了优化,这样写并不会增加运行耗时。
这个结论我是参考网友的结论,可能不太准确,我从运行时间上做了一个简单的验证
1 | ### 第二个sql |
上面两个sql语句:
- 第一个sql运行时间:
1mins, 10sec
- 第二个sql运行时间:
1mins, 6sec
可以看到,并没有增加多少运行时间。
5. 总结
所有的关键字后面都可以用表的别名,而字段的别名根据sql的执行顺序来判断。
但是,在mysql中:
group by
中可以使用字段别名- where中不能使用别名
order by
中可以使用别名
mysql特殊是因为mysql中对查询做了加强。其余像oracle、hive中别名的使用都是严格遵循sql执行顺序的。
【参考资料】