可以对窗口函数之后再加条件_SQL 窗口函数——解决实际问题
窗口函數(shù)是指什么?為什么要用它?怎么用?有哪些經(jīng)典的案例?
1)窗口函數(shù)是什么?
窗口函數(shù)是OLAP(online analytical processing),顧名思義,可以對數(shù)據(jù)庫內(nèi)的數(shù)據(jù)實時分析處理。通俗來講,把一簇大的數(shù)據(jù)拆分成多個范圍,把一面墻劃分成多個窗口。
<窗口函數(shù)>一般有以下兩種,
1、專用窗口函數(shù),包括rank,dense_rank,row_number等。
2、聚合函數(shù),如sum,avg,count,max,min等。
特點:
1、窗口函數(shù)有特定的語法結(jié)構,使用起來就像一個獨立的子句。
<2、窗口函數(shù)一般用于對where或者group by子句處理后的數(shù)據(jù)進行操作,(很明顯按照sql執(zhí)行順序)所以窗口函數(shù)原則上只能寫在select子句中。
窗口函數(shù)有什么用?
2)窗口函數(shù)怎么使用?
專用窗口函數(shù)
select#以成績表score為例,要求“在每個課程內(nèi)按成績排名”
rank+partition by和group by子句的區(qū)別:前者是分組排名后總行數(shù)不變,后者分組匯總后總行數(shù)改變?yōu)閹状箢悇e。前者分組排序后返回新列且有排好序的數(shù)值,后者分組后產(chǎn)生一個虛擬表用于后續(xù)處理。總結(jié)如下:
簡單來說,窗口函數(shù)的功能:
3)幾個專用窗口函數(shù)的區(qū)別:
rank正常排序,并列的次序會占用位置;
dense_rank緊密排序,并列的次序不會占用位置,依然按自然數(shù)順延;
row_number行數(shù)排序,完全不考慮并列的情況,按照行數(shù)依次排序;
面試經(jīng)典排名問題(分組功能可選)
在庫中score表中的內(nèi)容,記錄了每個學生所選的課程,和對應的成績。
#現(xiàn)在需要按成績來排名,如果兩個分數(shù)相同,那么排名要是并列的且不占位置,類似1,1,1,2;
面試經(jīng)典topN問題
比如如何找到每個類別下的number1?如何找到每個類別下XX方面排在前面的5個商品?
實質(zhì)就是常見的:分組取最大值,最小值,每組最大的N條記錄(topN記錄)。
在庫中score表中的內(nèi)容,記錄了每個學生所選的課程,和對應的成績。
#1每組最大記錄:按課程號分組取成績最大值所在行的全部數(shù)據(jù);
#2每組最小記錄:按課程號分組取成績最小值所在行的全部數(shù)據(jù);
#3每組最大的N條記錄:查詢每個學生各科成績前兩名的記錄
解題思路:針對1,2兩題,group by子句和匯總函數(shù)不能得到全部的行和列數(shù)據(jù),因此考慮使用“匯總函數(shù)+子查詢”結(jié)合使用得到完整的數(shù)據(jù)。
解題思路:針對3題,同樣的group by子句不能得到全部的行和列數(shù)據(jù),而且order by+limit也不適用于分別取出每一組內(nèi)的限定行數(shù)。
而由上面的對比可知,窗口函數(shù)rank() 能夠?qū)崿F(xiàn)在分組的同時保留全部數(shù)據(jù)且進行排序,因而topN適用窗口函數(shù)一步到位:
正確寫法,窗口函數(shù)使用后再作為表子查詢窗口函數(shù)只能放在select子句中,因此直接在where子句中使用窗口函數(shù)中的字段作為過濾條件,會報錯。顯然使用窗口函數(shù)解決topN問題更加流暢,上面1,2題同樣可以按照3題的思路進行解決。
select4)聚合函數(shù)作為窗口函數(shù)
將聚合函數(shù)替代專用窗口函數(shù)(rank())的位置即可。語法如下::
select 比如0004號,在使用sum窗口函數(shù)后的結(jié)果,是對0001,0002,0003,0004號的成績求和,若是0005號,則結(jié)果是0001號~0005號成績的求和,以此類推。從上圖執(zhí)行結(jié)果來看,聚合函數(shù)作為窗口函數(shù),是對自身所處位置,以及位于自身記錄以上的數(shù)據(jù)進行sum,avg,max,min,count進行處理的結(jié)果。
注意:這里的自身記錄,以及自身記錄以上....一定要是有一個次序比如(0001,0002,0003),否則并列的話會都當作自身記錄,會在一起處理,幾行數(shù)據(jù)也會一致。下面有示例圖。
這樣使用窗口函數(shù)有什么用呢?
聚合函數(shù)作為窗口函數(shù),可以在每一行的數(shù)據(jù)里直觀的看到,截止到本行數(shù)據(jù),統(tǒng)計數(shù)據(jù)是多少(最大值、最小值等)。同時可以看出每一行數(shù)據(jù),對整體統(tǒng)計數(shù)據(jù)的影響。那么問題是?對使用聚合函數(shù)作為窗口函數(shù)時,+partition by分組后,此時還是對當前記錄和記錄之上的數(shù)據(jù)進行聚合處理?事實上相當于是對“組內(nèi)求平均”,因為此時組內(nèi)字段值是一樣的,(也即都算作當前記錄),一組作為一個框架處理。示例如下:score表中按課程號分組求平均成績...
如何在每個組內(nèi)進行比較
問題:以score表為例,查找單科成績高于該科目平均成績的學生名單
解題思路:第一思路是前面用過的“聚合函數(shù)+關聯(lián)子查詢”,也適合組內(nèi)比較或者組內(nèi)最大最小值一類。 第二思路是使用“聚合函數(shù)做窗口函數(shù)”,同時實現(xiàn)聚合,分組,排序等功能。如下:
這一部分理解上 出了偏差,一直糾結(jié)于成績大于avg_score上,認為avg_score是多個值,混淆到“列子查詢”上去了。 此處是表內(nèi)比較,數(shù)據(jù)一行一行執(zhí)行的。——說明對sql執(zhí)行順序和單步運行結(jié)果仍不夠熟悉;(篩選條件可以是常量,字段,表達式,函數(shù) 。。)
5)窗口函數(shù)的移動平均(rows...preceeding)
語法如下:
select這樣使用窗口函數(shù)有什么用呢?
由于這里可以通過preceding關鍵字調(diào)整作用范圍,在以下場景中非常適用:
在公司業(yè)績名單排名中,可以通過移動平均,直觀地查看到與相鄰名次業(yè)績的平均、求和等統(tǒng)計數(shù)據(jù)。直接使用聚合函數(shù)avg的窗口函數(shù) 來舉例說明,以score表為例:
#使用聚合函數(shù)avg的窗口函數(shù)查詢學生的平均成績(未移動平均前且用來排序的字段有并列值)
#使用聚合函數(shù)avg的窗口函數(shù)查詢學生的平均成績(未移動平均前且用來排序的字段唯一)
#使用聚合函數(shù)avg的窗口函數(shù)查詢學生的平均成績(移動平均后)
這三個不同的查詢結(jié)果體會一下。再看下面的例子,
這張圖中學號按次序排列,按照移動平均rows 2 preceding執(zhí)行后得到的。每一行得到的結(jié)果,都是當前行和前面2行的平均(共3行)。想要計算當前行與前n行(共n+1行)的平均時,只要調(diào)整rows…preceding中間的數(shù)字即可。
框架:在移動平均中,被選出的數(shù)據(jù)可以理解為構成一個“框架”。數(shù)據(jù)的運算發(fā)生在這個框架之中。
窗口函數(shù)——知識點總結(jié)
1、窗口函數(shù)的語法
<1)其中<窗口函數(shù)>的位置,可使用以下兩種函數(shù):①專用窗口函數(shù),如rank,dense_rank,row_number等適合“經(jīng)典排序問題”“排序topN問題”等;②聚合函數(shù),如sum,avg,count,max,min等適合“組內(nèi)比較、篩選問題”等;
2)partition by子句可以省略,也就是不指定分組。
2、窗口函數(shù)有以下功能:
1)可同時實現(xiàn)分組(partition by)和排序(order by)的功能;
2)且不減少原表的行數(shù),所以經(jīng)常用來在每組內(nèi)排名;
3、注意事項
1)窗口函數(shù)原則上只能寫在select子句中;
2)因為只能放在select子句中,所以如果需要對窗口函數(shù)的結(jié)果進行條件篩選,而SQL主查詢中select執(zhí)行順序靠后,因此可以考慮把select 窗口函數(shù)改成一個表子查詢。執(zhí)行順序就變成了第一順位。
4、應用場景
總結(jié)
以上是生活随笔為你收集整理的可以对窗口函数之后再加条件_SQL 窗口函数——解决实际问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python爬虫课件_Python爬虫教
- 下一篇: pb 窗口数据修改sql_大数据hado