一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
在上一文中已经介绍了窗口函数的一些理论知识,以及实用案例,和一些概念,本文主要是实操方面的内容,包括窗口函数结合其他函数实现一些具体的功能,包括row_number()、RANK()、DENSE_RANK()等等。
前面已经说了窗口函数的表达式
Function() over (Partition By Column1,Column2,Order By Column3)
1、row_number函数 作用:多级分组
常见使用方法:row_number() over (Partition By Column1,Column2,Order By Column3) as n
具体功能描述:row_number()的作用就是对窗口函数内的行进行分组,先按照字段1和字段2进行排序分组,再将分组的结果集分别进行按照字段3的排序分组,并且要有分组结果进行排序,从1开始排名,遇到相同值按照表中记录的顺序进行排列。常用于根据某个字段去重且获取最新纪录,这可以叫做取值型窗口函数。
over() 窗口函数:规定了分析性函数作用下的数据窗口取值大小,在不同的行数内这个取值大小也不一样。
其中Partition By的作用是分区,Order By的作用是排序。这些可以组合一起使用也可以没有,随需求而定。
下面看一下具体案例:
left join
(
select
student_id -- 订单id
,row_number() over(partition by student_id ,grade_id order by create_time desc) as rk
from student_date
where pt = '${-1d_pt}'
and gound='1'
and student_id <> ''
) t2
on t2.rk = 1
and t0.student_id = t2.student_id
2、RANK函数
RANK():分组后,从1开始排名,遇到相同值会在名次中留下空位
即在排序相同的时候,序号标记的是一样的,即n值是相同的,但是总数不会变化,相同值也会一起计数,只不过相同值的排序是一样的。
3、DENSE_RANK函数
DENSE_RANK():分组后,从1开始排名,遇到相同值不会留下空位
和RANK()正好相反,相同值的排序号也是一样,但是总数就会减少,因为相同值不会作为计数的内容,只会计一次,所以总数会比全部数据量少。可以下面的例子分别验证一下结果。
select
user_name,
pv,
row_number() over (partition by sir_id,dt order by pv desc) as ord_1,
RANK() over (partition by sir_id,dt order by pv desc) as ord_2,
DENSE_RANK() over (partition by sir_id,dt order by pv desc) as ord_3
from user_view
where dt='20200803'
and sir_id='A20'