【Hive】group by 分组聚合后使用窗口函数

文章目录

  • 1. group by 分组聚合后使用排序窗口函数
    • 1.1 两种思路 与 简单例子
    • 1.2 新思路的解释
  • 2. group by 分组聚合后使用聚合窗口函数
  • 3. group by 分组聚合后使用分析窗口函数

1. group by 分组聚合后使用排序窗口函数

1.1 两种思路 与 简单例子

group by 之后,要对分组结果按照某种规则进行排序。该如何做?

  1. 常规思路:使用 order by 关键字排序
  2. 新思路:由于窗口函数会改变数据集的顺序,所以可以使用 窗口函数。此时的一个特点是 窗口函数内的order by 后面必须是聚合函数

以上还是有点抽象,通过例子说明:
在这里插入图片描述

  1. 常规思路:

    -- SQL:功能:筛选出总支付金额在前20%的用户
    select
    	user_name
    from (
    	select
    		-- SQL:功能:使用窗口函数为总支付金额在前20%的用户打上标签
    		user_name,
    		ntile(5) over(sum_pay desc) as level 
    	from (
    		-- SQL功能:计算每个用户的总支付金额
    		select
    			user_name,
    			sum(pay_amount) as sum_pay
    		from user_sales_table
    		group by user_name
    	) t1
    ) t2
    where level = 1
    
  2. 新思路:

    -- SQL:功能:筛选出总支付金额在前20%的用户
    select
    	user_name
    from (
    	-- SQL功能:每个用户按照总支付金额由大到小,并为前20%的用户打上标签
    	select
    		user_name,
    		ntile(5) over(order by sum(pay_amount) desc) as level
    	from user_sales_table
    	group by user_name
    ) t
    where level = 1
    

通过以上,可以明显的看出新思路少了一层嵌套,执行效率更高。

1.2 新思路的解释

从两点解释:

  1. 窗口函数的操作是指 group by 之后的数据集上进行操作的。
  2. 窗口函数:
    1. partition by是分区,按照字段值放入不同分区
    2. order by是对每个分区的 数据行 进行排序。
      • 当使用group by分组时,此时放入分区内的 每一个数据行分别对应一组数据,所以order by后面需要指名一组数据如何变为一行数据,也就是说需要使用 聚合函数,然后按照分区排序。
      • 当不使用 group by 分组时,此时放入分区内的数据就是数据行,一一对应,所以order by 后面不需要接聚合函数,此时表现为与group by + order by逻辑一样。

再拿一个难一点的例子举例:

  • 问题:SQL136 每类试卷得分前3名

  • 代码:

    select tag as tid, uid, ranking 
    from (
        select
            t2.tag,
            t1.uid,
            row_number() over (order by max(t1.score) desc, min(t1.score) desc, t1.uid desc) as ranking
        from exam_record as t1
            left join examination_info as t2 on t1.exam_id = t2.exam_id
        group by t1.uid, t2.tag
    ) as t
    where ranking <= 3;
    

2. group by 分组聚合后使用聚合窗口函数

待补充

3. group by 分组聚合后使用分析窗口函数

待补充

你可能感兴趣的:(#,Hive,java,数据库,开发语言)