????????前面?zhèn)z個章節(jié)我們介紹了窗口函數(shù)仆潮、滑動窗口函數(shù)的概念褂微,接下來我們介紹一下PG支持的原生通用窗口函數(shù)箫章,總共11個(9.6版本,中國社區(qū)官網(wǎng)文檔地址)
1讲逛、row_number 函數(shù)
row_number函數(shù)可以給每隔數(shù)據(jù)行返回一個虛擬的自增ID,也就是相當于給行分配一個編號,這些編號不會出現(xiàn)重復店诗,即使over()里面沒有按照字段排序字段也能正常工作裹刮,
select country_name,"year",gdp,row_number() over(order by country_name,"year")
from country_gdp_year_final?
where country_code in('CHN','JPN','USA','DEU','CAN','FRA') and "year" between 2012 and 2017;
2、rank函數(shù)
rank的官方解釋是:帶間隙的當前行排名庞瘸; 與該行的第一個同等行的row_number相同
select country_name,"year",gdp,rank() over(order by "year" desc)
from country_gdp_year_final?
where country_code? in('CHN','JPN','USA','DEU','CAN','FRA');
從上面的的結(jié)果我們可以看出 rank函數(shù)和row_number一樣可以將行編號捧弃,但是號碼可能重復,比如我們按照年份排序擦囊,年份相同的話rank值相同违霞,2017年的數(shù)據(jù)rank直接跳到了7,這就相當于上學的時候考試瞬场,用rank計算排名的話买鸽,如果同年級出現(xiàn)三個并列的第一名的話,那么計算的結(jié)果將是三個人的rank值都是第一贯被,但是實際上的第二高的分數(shù)的同學會被rank排名為第四名眼五,如果我們想第二高的分數(shù)的排名為2,我們可以使用dense_rank函數(shù);
3彤灶、dense_rank函數(shù)
select country_name,"year",gdp,dense_rank() over(order by "year" desc)
from country_gdp_year_final?
where country_code? in('CHN','JPN','USA','DEU','CAN','FRA');
????????從上面的結(jié)果我們可以看出dense_rank函數(shù)會把編號弄得更加緊密看幼,中間不會出現(xiàn)像rank那樣的斷層編碼。
4幌陕、percent_rank函數(shù)
????????官方文檔解釋:當前行的相對排名=(rank- 1) / (總行數(shù) - 1) ,
? ??????排名和rank值成正相關诵姜,rank值相同的行號?percent_rank獲取的結(jié)果也一樣,返回的結(jié)果是個小數(shù)范圍在[0,1]之間搏熄,可以等于0或者1
select country_name,"year",gdp,percent_rank() over(order by "year" desc),rank() over(order by "year" desc)
from country_gdp_year_final?
where country_code? in('CHN','JPN','USA') and "year" between 2014 and 2018;
5棚唆、cume_dist函數(shù)
????????官方文檔解釋:當前行的相對排名=(rank- 1) / (總行數(shù) - 1) ,
? ??????排名和rank值成正相關心例,rank值相同的行號?percent_rank獲取的結(jié)果也一樣宵凌,返回的結(jié)果是個小數(shù)范圍在[0,1]之間,可以等于0或者1
select country_name,"year",gdp,percent_rank() over(order by "year" desc),cume_dist() over(order by "year" desc),rank() over(order by "year" desc)
from country_gdp_year_final?
where country_code? in('CHN','JPN','USA') and "year" between 2014 and 2018;
6契邀、ntile函數(shù)
官方文檔解釋:從1到參數(shù)值的整數(shù)范圍摆寄,盡可能等分分區(qū),
????????ntile(num_buckets)坯门,num_buckets的值表示將結(jié)果集分成num_buckets組微饥,有限填滿前面的組,最后一組可能出現(xiàn)個數(shù)不足(非等分)情況古戴,實際上就是把每隔行分個組號欠橘。
select country_name,"year",gdp,percent_rank() over(order by "year" desc),cume_dist() over(order by "year" desc),
rank() over(order by "year" desc),ntile(4)? over(order by "year" desc)
from country_gdp_year_final?
where country_code? in('CHN','JPN','USA') and "year" between 2014 and 2018;
7、lag函數(shù)
????????官方文檔解釋:lag(value?anyelement?[,?offset?integer?[,?default?anyelement?]])现恼,返回value肃续, 它在分區(qū)內(nèi)當前行的之前offset個位置的行上計算;如果沒有這樣的行叉袍,返回default替代始锚。 (作為value必須是相同類型)。?offset和default都是根據(jù)當前行計算的結(jié)果喳逛。如果忽略它們瞧捌,則offset默認是1,default默認是空值
? ? ? ? 官方文檔的解釋很晦澀難懂润文,我們直接使用用例執(zhí)行一下看一下數(shù)據(jù)分布就好了
select country_name,"year",gdp,lag(gdp,1) over(order by "year" desc)
from country_gdp_year_final?
where country_code? in('CHN','JPN','USA') and "year" between 2014 and 2017;
從上圖可以知道當前行的lag值是當前行的前offset行的值姐呐,沒有的話就返回default,default不想存在的話就返回null,從數(shù)據(jù)姐過再去看官方文檔的解釋的話可能清晰很多,lag函數(shù)可以在結(jié)果集的行內(nèi)移動典蝌,經(jīng)常使用到的場景是計算今年和全年的年產(chǎn)量的差值曙砂,
select country_name,"year",gdp,lag(gdp,1) over(order by country_name, "year" desc) -gdp
from country_gdp_year_final?
where country_code? in('CHN','JPN','USA') and "year" between 2014 and 2017;
8、lead函數(shù)
官方文檔解釋:lead(value?anyelement?[,?offset?integer?[,?default?anyelement?]])?返回value骏掀,它在分區(qū)內(nèi)當前行的之后offset個位置的行上計算鸠澈;如果沒有這樣的行,返回default替代截驮。(作為value必須是相同類型)笑陈。offset和default都是根據(jù)當前行計算的結(jié)果。如果忽略它們侧纯,則offset默認是1新锈,default默認是空值
? ? 其實lead函數(shù)和lag函數(shù)的作用是相同的,如果lead的offset參數(shù)值為-N,那么lag的offset的參數(shù)為N的話計算結(jié)果是相同的眶熬,lag(gdp,-1)是lead(gdp,1)的替代
9妹笆、first_value、last_value娜氏、nth_value函數(shù)較為簡單不做介紹
????????至此我們講完了幾乎所有的窗口函數(shù)拳缠,希望這五篇關于PostgreSQL的文章能對大家在平時的開發(fā)中有所幫助