HQL max+struct实现开窗功能

HQL max+struct实现开窗功能

一、需求

这里有一张班级分数score表:

classnamescore
11188
11292
11399
22166
22298
22389

要求查找每个班级分数最高的人及其分数,输出如下:

classnamescore
11399
22298

二、实现

1.使用开窗函数实现

select class
     , name
     , score
from (select class
           , name
           , score
           , row_number() over (partition by class order by score desc) rn
      from score
     ) t
where rn = 1

说明:该方法为开窗函数的基本用法。

2.使用max+struct实现

step1
select class
	 , max(struct(score, name)) as tmp
from score 
group by class

输出:

classtmp
1{“col1”:99,“col2”:“13”}
2{“col1”:98,“col2”:“22”}

说明:struct里的字段,按顺序比较,若第一个字段(score)的值相等,则比较第二个字段(name),保留最大的一条数据。tmp的类型为struct。

step2
select class
     , tmp.col2 as name
     , tmp.col1 as score
from (
         select class
              , max(struct(score, name)) as tmp
         from score
         group by class
     ) t

说明:tmp的数据类型为struct,第一个字段(score)在结构体里的别名为col1,所以外层的select对tmp取值时的写法为tmp.co1,其他字段以此类推。

3.两种方法比较

优势一:

减少了排序或关联的操作,有更好的运行效率。

优势二

代码更简洁。尤其是需要同时取最大和最小记录的时候。

如需求改为求每个班的分数最大者和分数最小者,输出如下:

classname_maxscore_maxname_minscore_min
113991188
222982166
(1) 使用传统开窗函数
select class
     , max(if(rn_max = 1, name, '')) as name_max
     , max(if(rn_max = 1, score, 0)) as score_max
     , max(if(rn_min = 1, name, '')) as name_min
     , max(if(rn_min = 1, score, 0)) as score_min
from (select class
           , name
           , score
           , row_number() over (partition by class order by score desc) rn_max
           , row_number() over (partition by class order by score)      rn_min
      from score
     ) t
where rn_max = 1
   or rn_min = 1
group by class
(2) 使用max/min+struct方法
select class
     , tmp_max.col2 as name_max
     , tmp_max.col1 as score_max
     , tmp_min.col2 as name_min
     , tmp_min.col1 as score_min
from (
         select class
              , max(struct(score, name)) as tmp_max
              , min(struct(score, name)) as tmp_min
         from score
         group by class
     ) t

三、总结

提供了一种取最大/最小记录的新思路

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值