1、窗口函数
窗口函数的关键字 partition by 和 order by
partition by 是用来分组,即选择要看哪个窗口,类似于group by 子句的分组功能,但是partition by 子句并不具备group by 子句的汇总功能,并不会改变原始表中记录的行数。
order by是用来排序,即决定窗口内,是按哪种规则(字段)来排序的。
order by 升序降序和它自己本身的用法一致,默认升序,order by col desc 降序。
select product_name,
product_type,
sale_price,
rank() over (partition by product_type order by sale_price) as ranking
from product;
2、rank & dense_rank & row_number
rank() : 同名次保留,rank值不连续;100,100,100,50为1,1,1,4
dense_rank() : 同名次保留排序,rank值连续;100,100,100,50为1,1,1,2
row_number() : 按字面意思,行序的值
3、取得累计结果:
!!!这个是很实用的!!!
select product_id,
product_name,
sale_price,
sum(sale_price) over (order by product_id) as current_sum,
avg(sale_price) over (order by product_id) as current_avg
from product;
4、移动平均
!!!这个也是很实用的!!!
3是平均了所有的了,这个可以加个窗口,主要是用于按照一列排序后取定值窗口的平均,而不是像partition by一样对某一个col做分区之后的区域平均!!!
rows n preceding: 之前的n行加上自身行的窗口
rows between n preceding and m following: 之前的n行加上自身行加上之后的m行的窗口
注意没有 rows m following 的写法!!!!
如果要实现后m列的相加(含自身),要使用rows between 0 preceding and m following
5、group by 加上小计和合计
这个蛮实用的
只需要在本身的group by 语法后面加上with rollup
练习题:
答:本记录之前(含本记录)最大的sale_price 为此纪录Current_max_price字段
答:直接默认的就是null在第一位
select regist_date,
sum(sale_price) over (partition by regist_date) as sale_price_all_today
from product
order by regist_date;
答:1、不指定partition by就相当于以整体为一个分区。
2、我理解,窗口函数本身,应该是一种分组,类似于groupby ,但是 groupby是依附于键值(column)的,窗口是是依附于分区的,这种分区有可能是显式的,partition by ,也有可能是隐式的按位置 preceding 和 following 和order by。
分区之后的聚合应该和group by 的逻辑一样,group by之后再select聚合
那就应该是在SELECT部分做聚合+窗口over()