练习数据:
create table order_tab(
order_id int,
user_no varchar(3),
amount int,
create_date date
);
insert into order_tab values
(1,'001',100,'2019-01-01'),
(2,'001',300,'2019-01-02'),
(3,'001',500,'2019-01-02'),
(4,'001',800,'2019-01-03'),
(5,'001',900,'2019-01-04'),
(6,'002',500,'2019-01-03'),
(7,'002',600,'2019-01-04'),
(8,'002',300,'2019-01-10'),
(9,'002',800,'2019-01-16'),
(10,'002',800,'2019-01-22');
一、排序开窗函数
① row_number() – 相同值排名顺延,返回结果1、2、3、4
② rank() --相同结果排名相同,后续排名不连续,返回结果为 1、2、2、4
③ dense_rank() – 相同结果排名相同,后续排名顺延,返回结果为1、2、2、3
④ ntile(n) – 分组排名,将数据分为n组并返回对应组号1、2…n NTILE(n),用于将分组数据按照顺序切分成n片,返回当前切片值。将一个有序的数据集划分为多个桶(bucket),并为每行分配一个适当的桶数(切片值,第几个切片,第几个分区等概念)。它可用于将数据划分为相等的小切片,为每一行分配该小切片的数字序号。如果切片不均匀,默认增加第一个切片的分布。
select order_id,create_date,user_no,amount,
row_number() over (partition by user_no order by amount) as rowNumber,
rank() over (partition by user_no order by amount) as ranKs,
dense_rank() over (partition by user_no order by amount) as denseRank,
ntile(3) over (partition by user_no order by amount) as ntiles
from order_tab;
二、聚合开窗函数
① sum() – 分组求和
② count() – 分组求总数
③ min() – 分组求最小值
④ max() – 分组求最大值
⑤ avg() --分组求均值
select order_id,create_date,user_no,amount,
sum(amount) over (partition by user_no order by amount) as sum_num,
count(amount) over (partition by user_no order by amount) as count_num,
min(amount) over (partition by user_no order by amount) as min_num,
max(amount) over (partition by user_no order by amount) as max_num,
avg(amount) over (partition by user_no order by amount) as avg_num
from order_tab;
三、其他开窗函数
① lag(字段名,n,0) – 移位开窗函数,表示返回向上第n行指定字段对应数据。其中n代表向上偏移n行,0代表若偏移行数超出表范围则返回0也可以改成其他值,若不写则默认null
② lead(字段名,n,0) – 移位开窗函数,与lag()相反,表示返回向下第n行指定字段对应数据
③ first_value()-- 取分组内排序后,截止到当前行,第一个值
④ last_value() – 取分组内排序后,截止到当前行,最后一个值
select order_id,create_date,user_no,amount,
lag(amount,2,0) over (partition by user_no order by amount) as lag_num,
lead(amount,2,0) over (partition by user_no order by amount) as lead_num,
first_value(amount) over (partition by user_no order by amount) as first_value_num,
last_value(amount) over (partition by user_no order by amount) as last_value_num
from order_tab;