基本每次面試bi候選人的時候,為了了解候選人的sql基本功底,每次都會問到視窗函式,因為這個函式太好用了。下面就來簡單介紹下sql視窗函式的用法用途。
視窗函式作用於乙個資料行集合。視窗是標準的sql術語,用來描述sql語句內over子句劃定的內容,這個內容就是視窗函式的作用域。而在over子句中,定義了視窗所覆蓋的與當前行相關的資料行集、行的排序及其他的相關元素。1. 排名函式標準sql對視窗函式的第一次支援是在sql:1999的擴充套件文件中,當時,它們稱為「olap」函式。從那以後,每次標準版本的修訂都會增強對視窗函式的支援,直到現在的sql:2003、sql:2008、sql:2011。最新的sql標準版本,已經有了非常豐富和全面的視窗函式,顯示出標準委員會對這一概念的堅定,以及從更多視窗函式和更多功能兩個方面持續增強支援標準。
row_number/rank/dense_rank
視窗函式當然是這篇文章的重點了。視窗函式中,排名函式又是最常用的。視窗排序主要是指非全表排序,需要在某個維度下進行排序。。例如說現在想看各個department內部收入最多的人,這時候不能全表order by了,該怎麼取?
select
*,row_number() over ( partition by department order by revenue desc ) as row_number_result,
rank() over ( partition by department order by revenue desc) as rank_result,
dense_rank() over (partition by department order by revenue desc) as dense_rank_result
from
table
row_number() 則在排序相同時不重複,會根據順序排序。rank()排序相同時會重複,總數不會變 ,意思是會出現1、1、3這樣的排序結果;dense_rank() 排序相同時會重複,總數會減少,意思是會出現1、1、2這樣的排序結果。
sql標準支援4種用於排名計算的視窗函式。它們是:row_number、ntile、rank和dense_rank。在標準中,前兩者是一類,後兩者是另一類。row_number函式根據指定的順序,從1開始計算連續的行號。ntile函式把視窗分割槽裡的資料行分成數量大致相等的塊(根據輸入的塊數和指定的視窗排序)。2. 排序函式:分割槽最大/最小值
first_value/last_value
取的是分組內排序後,截止到當前行第乙個/最後乙個值
select
*,first_value(name) over (partition by department order by revenue desc ) as max_revenue_user, ## 分組取每個組的最大值對應的人
first_value(name) over (partition by department order by revenue) as min_revenue_user ## 分組取每個組的最大值對應的人
from
table
最後就會得到每個組裡的revenue最多和最少的人
3. 分布函式:累積百分比
cume_dist / sum() over
累積百分比的應用場景也很多,比如說,想看前xx%的使用者貢獻了xx%的總額。這個地方需要兩個函式的使用,1是xx%的使用者,2是xx%的總額。
select
*,cume_dist() over (partition by department order by revenue ) as cum_dist,
cume_dist(revenue) over (partition by department order by revenue )/sum(revenue) over (partition by department) as s
from
table
where
department = 'hr'
但a組這種無重複值的,結果是很好理解的。最後可以得到a部的revenue由高到低排序,xx%的人累積貢獻了xx%多少。
視窗分布函式主要為靜態統計服務提供資料的分布情況。sql server 2012引入了兩種視窗分布函式的支援:排名分布函式和逆分布函式。排名分布函式有兩種:percent_rank(百分位排名)和cume_dist(累積分布),逆分布函式也有兩個:percent_cont(百分位連續)和percentile_disc(百分位離散)。4.偏移函式lead/lag根據標準sql,分布函式計算資料行在視窗分割槽中的相對排名,把它表達成介於0~1之間的比值——我們大多數人把它看做百分比。
假設rk 為資料行的rank值,rank函式的視窗描述與分布函式的視窗描述相同。假設nr為視窗分區內資料行的行數。假設np為領先或與當前行的排序值相同的行的數目(為比當前rk減1大的最小rk值,如果當前的rk為最大值,np則等於nr)。
percent_rank(百分位排名)計算公式如下:(rk-1)/(nr-1),percent_rank(百分位排名)的計算公式如下:np/nr。
逆分布函式,通常叫百分位,我們可以把它執行的計算當作是排名分布函式的倒數。percentile_disc(百分位離散)函式(disc為離散分布模型)返回組中第乙個符合條件的值,條件是:其累計分布(cume_dist函式)大於等於輸入值。
函式lead和lag函式,這兩個函式一般用於計算差值,最適用的場景是計算花費時間。舉個例子,有資料是每個使用者瀏覽網頁的時間記錄,將記錄的時間錯位之後,進行兩列相減就可以得到每個使用者瀏覽每個網頁實際花費的時間。lead是用於統計視窗內往下第n行值,lag是用於統計視窗內往上第n行值。雖然目前我們這個資料不是時間資料,也可以使用這個函式操作一下。例如說,現在計算按revenue排序後,每個department的人他們的收入,以及和比他們花費排名更高一名的人的值,可以計算差值。
select *,
lead(revenue) over(partition by department order by revenue) next_revenue
from
table
視窗偏移函式包括兩種型別的函式。一種是偏移量是相對於當前行的,這個類別的包括lag和lead函式;另乙個類別函式的偏移量是相對於視窗框架的開始和結尾的,這個類別包括first_value、last_value和nth_value。第一類別中的函式(lag和lead)支援視窗分割槽子句以及視窗排序子句。當然,後者的存在賦予偏移量以邏輯意義。第二類別中的函式(first_value、last_value和nth_value)在支援視窗分割槽子句和排序子句的基礎上,還支援視窗框架子句。sql相關崗位面試前必須要知道的常用語句之一,你學會了麼?
Hive 視窗分析函式
1.lag col,n,default 用於統計視窗內往上第n行值 第乙個引數為列名,第二個引數為往上第n行 可選,預設為1 第三個引數為預設值 當往上第n行為null時候,取預設值,如不指定,則為null 2.lead col,n,default 用於統計視窗內往下第n行值 第乙個引數為列名,第二...
Hive 視窗函式與分析函式
描述lag lag 視窗函式返回分割槽中當前行之前行 可以指定第幾行 的值。如果沒有行,則返回null。lead lead 視窗函式返回分割槽中當前行後面行 可以指定第幾行 的值。如果沒有行,則返回null。first value first value視窗函式返回相對於視窗中第一行的指定列的值。l...
查詢問題的利器 Git Blame
譯者注 git採用sha1做為hash簽名演算法,在本書中,作者為了表達方便,常常使用sha來代指sha1.如果沒有特別說明,本書中的sha就是sha1的代稱.git blame sha1 file.c 0fcfd160 linus torvalds 2005 04 18 13 04 43 0700...