sparksql现在允许重用GROUPBY和ORDERBY中select表达式的结果?

ni65a41a  于 2021-06-26  发布在  Hive
关注(0)|答案(0)|浏览(284)

大约六个月前(2017年9月),我发布了一个问题,询问 SparkSQL 允许在GROUPBY和ORDERBY中重用select表达式的结果。答案是否定的,人们被迫使用不同的解决方法,比如写一个子查询或者在groupby中重复表达式(参见这里的帖子)
但我又试了一遍。也许我们已经升级到使用更新版本的sparksql了。我注意到了 SparkSQL 现在实际上允许重用。
更新了新的查询示例和新的观察结果
下面是一个例子。现在允许查询(新方式):

select 
  count(*) cnt,
  date(from_unixtime(t.starttime/1000)) as timeDate  
from someTable as t
group by 
  timeDate
order by 
  timeDate desc
/* Okay */

我们还能用老办法吗?根据我的实验,答案是肯定的和否定的。我不知道是否有错误或它的意图。
允许此查询:

select 
  count(*) cnt,
  date(from_unixtime(t.starttime/1000)) as timeDate  
from someTable as t
group by 
  date(from_unixtime(t.starttime/1000))
order by 
  date(from_unixtime(t.starttime/1000)) desc
/* Okay */

但以下查询将触发异常:

select 
  count(*) cnt,
  cast(date(from_unixtime(t.starttime/1000)) as date) as timeDate  
from someTable as t
group by 
  date(from_unixtime(t.starttime/1000))
order by 
  starttime desc  
/* Error: AnalysisException */

错误:

Error: org.apache.spark.sql.AnalysisException: \
cannot resolve '`starttime`' given input columns: \
[cnt, timeDate]; line 7 pos 9;

请参阅下面的更多失败/成功案例
我明白在上面的例子中 cast(... as date) 是多余的,但这里我只是想探索一下语法允许什么。如果我们使用新的方法(重用select表达式的结果),就没有问题了。

select 
  count(*) cnt,
  cast(date(from_unixtime(t.starttime/1000)) as date) as timeDate  
from someTable as t
group by 
  timeDate
order by 
  timeDate desc
/* Okay */

我确实喜欢这种新方法,但我想确保我的观察是正确的。有人能证实吗?
我忘了六个月前的版本是什么,但这里是当前的软件版本:
我们的软件版本:
hdfs:2.7.3
Hive:1.2.1
hbase:1.1.2版
Spark:2.0.2
Yarn:2.7.3
spark thrift服务器:2.2.0
squirrel sql客户端:3.8.0
附录:更多失败/成功的例子
似乎order by必须以某种方式与group by匹配,否则将引发异常。

select 
  count(*) cnt,
  date(from_unixtime(t.starttime/1000)) as timeDate  
from someTable as t
group by 
  date(from_unixtime(t.starttime/1000))
order by 
  t.starttime desc 
/* Error: AnalysisException */  

select 
  count(*) cnt,
  cast(date(from_unixtime(t.starttime/1000)) as date) as timeDate  
from someTable as t
group by 
  cast(date(from_unixtime(t.starttime/1000)) as date)
order by 
  cast(date(from_unixtime(t.starttime/1000)) as date) desc   
/* Okay */

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题