文章目录
- 1. group by 分组聚合后使用排序窗口函数
- 1.1 两种思路 与 简单例子
- 1.2 新思路的解释
- 2. group by 分组聚合后使用聚合窗口函数
- 3. group by 分组聚合后使用分析窗口函数
1. group by 分组聚合后使用排序窗口函数
1.1 两种思路 与 简单例子
group by 之后,要对分组结果按照某种规则进行排序。该如何做?
- 常规思路:使用
order by
关键字排序 - 新思路:由于窗口函数会改变数据集的顺序,所以可以使用
窗口函数
。此时的一个特点是 窗口函数内的order by 后面必须是聚合函数
以上还是有点抽象,通过例子说明:
-
常规思路:
-- 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
-
新思路:
-- 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 新思路的解释
从两点解释:
- 窗口函数的操作是指
group by
之后的数据集上进行操作的。 - 窗口函数:
partition by
是分区,按照字段值放入不同分区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 分组聚合后使用分析窗口函数
待补充