碎語
- 學(xué)習(xí)的正態(tài)曲線:入門容易宋梧,精通難
- 積累的正態(tài)曲線:先越讀越多刨疼,后越讀越少
什么是開窗函數(shù)
很多場景比如排序虐译,累計求和等瘪板,如果沒有開窗函數(shù),那么就要使用很復(fù)雜的子查詢或是存儲過程才能做到漆诽。為了解決這些問題侮攀,就有了現(xiàn)在的開窗函數(shù),MySQL是從8.0版本之后才有了開窗函數(shù)厢拭,如果要使用兰英,那么必須下載MySQL8.0以上的版本
開窗函數(shù)主要是為了給行定義一個窗口,可以理解就是一個分組,但是和group by 的區(qū)別在于它不是返回一個聚合值供鸠,而是每一行都能返回一個值畦贸。舉個例子,咱們要求每個月銷量和當年總銷量以及每個月的銷量占比楞捂,這時候用sum() 和開窗就很容易了
數(shù)據(jù)參考:數(shù)據(jù)分析師經(jīng)常遇到的SQL場景解析
select
sal_year,
sal_month,
sum_sale,#銷量
sum(sum_sale) over(partition by sal_year) as cumu_sal,##年總銷量
sum_sale/(sum(sum_sale) over(partition by sal_year)) as ratio ##每個月銷量占全年銷量的占比
from
(select
year(date(order_date) )as sal_year,
month(date(order_Date) )as sal_month,
sum(sales) as sum_sale
from
chaoshi.order
group by
year(date(order_date) ),
month(date(order_Date) )
)a
order by
sal_year,
sal_month;
開窗結(jié)構(gòu)
函數(shù)+開窗函數(shù):row_number() over()
row_number() over(partition by xx order by yy rows between zz and aa)
- partition by:分組薄坏,顧名思義就是以什么字段進行分組,形式跟group by 一樣
- order by : 排序寨闹,對分完組后的數(shù)據(jù)胶坠,進行組內(nèi)的排序
- rows between :窗口,計算的窗口繁堡,between后可以跟如下的內(nèi)容:
- unbounded preceding:第一行
- unbounded following:最后一行
- current row:當前行
- N preceding:前N行
- N following:后N行
- 一般省略了rows的時候默認都是從開窗后的第一行到當前行沈善,后面的具體例子會講解
- row_number() 就是一個函數(shù),開窗一般都是與排序和聚合函數(shù)一起使用
函數(shù)
排名開窗函數(shù)
- row_number ():排序之后不管有沒有重復(fù)值都是一直往上再加序號
- dense_rank():排序之后遇到重復(fù)值會生成一樣的序號帖蔓,但是接下來的序號連續(xù)
- rank():排序之后遇到重復(fù)值會生成一樣的序號矮瘟,接下來的序號不連續(xù),具體如下栗子
栗子
with test as (##創(chuàng)建了一個臨時表
select
1 as num
from
dual
union all
select
2 as num
from
dual
union all
select
2 as num
from
dual
union all
select
3 as num
from
dual
union all
select
4 as num
from
dual
)
select
num ,
row_number() over(order by num ) as row_number1,
rank() over(order by num) as rank1,
dense_rank() over(order by num) as dense_rank1
from
test ##上面的臨時表test
結(jié)果
聚合開窗函數(shù)
可以和很多聚合函數(shù)一起使用塑娇,如:sum()/count()/min()/max()
結(jié)束語
如果我不能讓您看懂澈侠,那是我的問題,如果有疑問可以關(guān)注我埋酬,然后私聊我哨啃,我會盡最大的努力幫助你。如果覺得對你有幫助写妥,請幫忙點贊/關(guān)注拳球,謝謝!