一、窗口函数定义
窗口函数允许将查询的结果集,或查询的逻辑划分,划分为称为窗口分区的行组。
通俗来说,窗口函数的名字来自于它的工作方式,你可以想象它就像在你的数据上打开一个'窗口',然后对这个'窗口'内的数据进行某种计算。这个'窗口'可以是整个数据集,也可以是数据集的一部分。这个'窗口'可以根据需要移动,也就是说,窗口函数可以在每一行的不同'窗口'中进行计算。
因窗口函数用法相似,这里不会举例全部窗口函数,以几个常用的窗口函数为例,做一个实操,让大家知晓它们的用法,更多内容大家可以在官网上查询。
这个与聚合窗口函数用法虽然相似,但是使用场景是不一样的。在实际的项目中,像LEAD、LAG、排名之类的会使用得比较频繁。
SELECT
class,
val,
offset,
--LEAD函数 返回当前行之后的行偏移,LAG函数,返回当前行之前偏移行的值,如果指定了偏移值,则根据偏移值取,其默认值为1
LEAD(val) OVER (PARTITION BY class ORDER BY val) AS lead,
--LEAD(val, offset, -val)这部分的作用是返回当前行offset偏移量之后的行的val字段的值。如果偏移后的行不存在(即偏移超出了分组的行数),则返回-val。
LEAD(val,offset,-val) OVER (PARTITION BY class ORDER BY val) AS lead2,
LAG(val) OVER (PARTITION BY class ORDER BY val) AS lag,
LAG(val,offset,-val) OVER (PARTITION BY class ORDER BY val) AS lag2,
--DENSE_RANK函数 执行与RANK函数相同的排名操作,但是当发现并列时,排名编号不会跳过。
--RANK函数 返回分区内一行的排名,从1开始。
--ROW_NUMBER函数 在结果集的分区内对行进行顺序编号,每个分区的第一行被指定为1。
--总结:row_num,遇到重复的会直接往下排12345,RANK遇到重复的会相同,下一个数排名跳过12335,ROW_NUMBER遇到重复的会相同,下一个数排名不跳过 12334
ROW_NUMBER() OVER (PARTITION BY Class ORDER BY val) AS ROW_NUM,
RANK() OVER (PARTITION BY Class ORDER BY val) AS RANK,
DENSE_RANK() OVER (PARTITION BY Class ORDER BY val) AS DENSE_RANK,
--PERCENT_RANK函数 根据窗口的ORDER BY规定,计算小于或大于当前值的数值的百分比。
PERCENT_RANK() OVER (PARTITION BY Class ORDER BY val) AS Percent_Rank,
--PERCENTILE_DISC函数 返回累积分布值大于或等于常数百分位值的第一个值,可以设置不同的比例
PERCENTILE_DISC(0.125) WITHIN GROUP (ORDER BY val) OVER (PARTITION BY class) AS pd1,
PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY val) OVER (PARTITION BY class) AS pd2,
PERCENTILE_DISC(0.875) WITHIN GROUP (ORDER BY val) OVER (PARTITION BY class) AS pd3,
--PERCENTILE_CONT函数 使用常数的百分位值返回插值。
--如果 fraction 是 0,PERCENTILE_CONT 返回排序后的第一个非空值。
--如果 fraction 是 1,PERCENTILE_CONT 返回排序后的最后一个非空值。
--如果 fraction 是在 0 到 1 之间的一个数,那么 PERCENTILE_CONT 会找到两个相邻的数值,它们的位置分别是最接近 fraction 的上界和下界,然后返回这两个数值的线性插值。
PERCENTILE_CONT(0) WITHIN GROUP (ORDER BY val) OVER (PARTITION BY class) AS pc1,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY val) OVER (PARTITION BY class) AS pc2,
PERCENTILE_CONT(0.875) WITHIN GROUP (ORDER BY val) OVER (PARTITION BY class) AS pc3
FROM T;
order by class,val
;