语法:
分析函数over(partition by 列名 order by 列名 rows between 开始位置 and 结束位置)
常用分析函数:
聚合类:avg() sum() max() min()
排名类 :
row_number() 按照值排序时产生一个自增编号,不会重复
rank() 按照值排序时产生一个自增编号,值相等时会重复,会产生空位
dense_rank() 按照值排序时产生一个自增编号,值相等时会重复,不会产生空位
其他类:
lag(列名,往前的行数,[行数为null时的默认值,不指定为null])
lead(列名,往后的行数,[行数为null时的默认值,不指定为null])
ntile(n) 把有序分区中的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,ntile返回此行所属的组的编号
注意点:
over()函数中的分区,排序,指定窗口范围可组合使用也可以不指定,根据不同的业务需求结合使用
over()函数中如果不指定分区,窗口大小是针对查询产生的所有数据,如果指定了分区,窗口大小是针对每个分区中的数据
over()函数中的窗口范围说明:
current row :当前行
unbounded:起点,unbounded preceding 表示从前面的起点, unbounded following表示到后面的终点
n preceding :往前n行数据
n following:往后n行数据
实战案例1:
原始数据(用户购买明细数据)
name,orderdate,cost jack,2017-01-01,10 tony,2017-01-02,15 jack,2017-02-03,23 tony,2017-01-04,29 jack,2017-01-05,46 jack,2017-04-06,42 tony,2017-01-07,50 jack,2017-01-08,55 mart,2017-04-08,62 mart,2017-04-09,68 neil,2017-05-10,12 mart,2017-04-11,75 neil,2017-06-12,80 mart,2017-04-13,94 建表加载数据 vi business.txt create table business ( name string, orderdate string, cost int )ROW FORMAT DELIMITED FIELDS TERMINATED BY ','; load data local inpath "/opt/module/data/business.txt" into table business;
需求
(1)查询在2017年4月份购买过的顾客及总人数
分析:按照日期过滤、分组count求总人数(分组为什么不是用group by?自己思考) select name, orderdate, cost, count(*) over() total_people from business where date_format(orderdate,'yyyy-MM')='2017-04';
(2)查询顾客的购买明细及月购买总额
分析:按照顾客分组、sum购买金额 select name, orderdate, cost, sum(cost) over(partition by name) total_amount from business;
(3)上述的场景,要将cost按照日期进行累加
分析:按照顾客分组、日期升序排序、组内每条数据将之前的金额累加 select name, orderdate, cost, sum(cost) over(partition by name order by orderdate rows between unbounded preceding and current row) cumulative_amount from business;
(4)查询顾客上次的购买时间
分析:查询出明细数据同时获取上一条数据的购买时间(肯定需要按照顾客分组、时间升序排序) select name, orderdate, cost, lag(orderdate,1) over(partition by name order by orderdate) last_date from business;
(5)查询前20%时间的订单信息
分析:按照日期升序排序、取前20%的数据 select * from ( select name, orderdate, cost, ntile(5) over(order by orderdate) sortgroup_num from business ) t where t.sortgroup_num=1;