高級函數_分析函數與窗口函數

高級函數_分析函數與窗口函數

分析函數往往與窗口函數一起使用,over()為窗口函數

一、分析函數

1.01、排名

分析函數中的排名函數可以針對窗口中的記錄生成排序序號,常用的排名函數有:rank()、dense_rank()、row_number()

語句:select * from employee;

EMP_ID ? ? ? ? ? ? ? ? ? ? EMP_NAME ? ? ? ? ? ? ? ? EMP_SALARY

------------------------ ------------------------------ ----------------------

0001 ? ? ? ? ? ? ? ? ? ? ? ? ? 張三 ? ? ? ? ? ? ? ? ? ? ? ? ? 5000

0002 ? ? ? ? ? ? ? ? ? ? ? ? ? 李四 ? ? ? ? ? ? ? ? ? ? ? ? ? 4500

0003 ? ? ? ? ? ? ? ? ? ? ? ? ? 趙飛 ? ? ? ? ? ? ? ? ? ? ? ? ? 6000

0004 ? ? ? ? ? ? ? ? ? ? ? ? ? 韓明 ? ? ? ? ? ? ? ? ? ? ? ? ? 4500

0005 ? ? ? ? ? ? ? ? ? ? ? ? ? 王蘭 ? ? ? ? ? ? ? ? ? ? ? ? ? 4500

0006 ? ? ? ? ? ? ? ? ? ? ? ? ? 李麗 ? ? ? ? ? ? ? ? ? ? ? ? ? 6000

語句:select emp_name,rank()over(order by emp_salary) position from employee;

EMP_NAME ? ? ? ? ?POSITION

--------------------- ?----------------------

王蘭 ? ? ? ? ? ? ? ? ? ? ? ? ? 1

李四 ? ? ? ? ? ? ? ? ? ? ? ? ? 1

韓明 ? ? ? ? ? ? ? ? ? ? ? ? ? 1

張三 ? ? ? ? ? ? ? ? ? ? ? ? ? 4

李麗 ? ? ? ? ? ? ? ? ? ? ? ? ? 5趙飛 ? ? ? ? ? ? ? ? ? ? ? ? ? 5

rank()函數對于相同排名的記錄,會返回相同的排序序號,當出現多個排名?相同的記錄時,下一排名序號,將根據前一排名個數進行跳躍,如里面沒有出現2和3,直接跳到4

語句:select emp_name,dense_rank()over(order by emp_salary) position from employee;

EMP_NAME ? ? ? ? ? ??POSITION

------------------------?----------------------

王蘭 ? ? ? ? ? ? ? ? ? ? ? ? ? 1

李四 ? ? ? ? ? ? ? ? ? ? ? ? ? 1

韓明 ? ? ? ? ? ? ? ? ? ? ? ? ? 1

張三 ? ? ? ? ? ? ? ? ? ? ? ? ? 2

李麗 ? ? ? ? ? ? ? ? ? ? ? ? ? 3

趙飛 ? ? ? ? ? ? ? ? ? ? ? ? ? 3

dense_rank()函數對于相同排名的記錄,會返回相同的排序序號,當出現多個排名?相同的記錄時,不會進行跳躍

語句:select emp_name,row_number() over(order by emp_salary) position from employee;

EMP_NAME ? ? ? ? ? ? ??POSITION

------------------------ ----------------------

王蘭 ? ? ? ? ? ? ? ? ? ? ? ? ? 1

李四 ? ? ? ? ? ? ? ? ? ? ? ? ? 2

韓明 ? ? ? ? ? ? ? ? ? ? ? ? ? 3

張三 ? ? ? ? ? ? ? ? ? ? ? ? ? 4

李麗 ? ? ? ? ? ? ? ? ? ? ? ? ? 5

趙飛 ? ? ? ? ? ? ? ? ? ? ? ? ? 6row_number()函數每條記錄會存在唯一的排序序號

二、分區窗口

利用partition by 可以指定?分區窗口

語句:?select * from employee;

EMP_ID ? ? ? ? ? ? EMP_NAME ? ? ?EMP_SALARY ? ?EMP_DEPARTMENT

-------------------- -----------------?---------------------- --------------------

0001 ? ? ? ? ? ? ? ? 張三 ? ? ? ? ? ? ? ? 5000 ? ? ? ? ? ? ? ? ? 設計部

0002 ? ? ? ? ? ? ? ? 李四 ? ? ? ? ? ? ? ? 4500 ? ? ? ? ? ? ? ? ? 工程部

0003 ? ? ? ? ? ? ? ? 趙飛 ? ? ? ? ? ? ? ? 6000 ? ? ? ? ? ? ? ? ? 項目部

0004 ? ? ? ? ? ? ? ? 韓明 ? ? ? ? ? ? ? ? 4500 ? ? ? ? ? ? ? ? ? 項目部

0005 ? ? ? ? ? ? ? ? 王蘭 ? ? ? ? ? ? ? ? 4500 ? ? ? ? ? ? ? ? ? 工程部

0006 ? ? ? ? ? ? ? ? 李麗 ? ? ? ? ? ? ? ? 6000 ? ? ? ? ? ? ? ? ? 項目部

語句:select t.*,dense_rank() over(partition byemp_department order by emp_salary) position from employee t order by t.emp_id;

EMP_ID ? ? ? ? ? ???EMP_NAME ? ? ? ??EMP_SALARY ? ? ? ? ??EMP_DEPARTMENT ? ? ? POSITION

-------------------- -------------------- ---------------------- -------------------- - ? ? ? ? ? ? ? ? ---------------------

0001 ? ? ? ? ? ? ? ? ??張三 ? ? ? ? ? ? ? ? ? ? ?5000 ? ? ? ? ? ? ? ? ? ? ? ? ??設計部 ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ?1

0002 ? ? ? ? ? ? ? ? ??李四 ? ? ? ? ? ? ? ? ? ? ?4500 ? ? ? ? ? ? ? ? ? ? ? ? ??工程部10003 ? ? ? ? ? ? ? ? ??趙飛 ? ? ? ? ? ? ? ? ? ???6000項目部20004 ? ? ? ? ? ? ? ? ??韓明 ? ? ? ? ? ? ? ? ? ? ?4500項目部10005 ? ? ? ? ? ? ? ? ??王蘭 ? ? ? ? ? ? ? ? ? ? ?4500工程部10006 ? ? ? ? ? ? ? ?? ?李麗 ? ? ? ? ? ? ? ? ? ? ?6000項目部2

分區內可以求和

語句:select t.*,sum(emp_salary)over(partition byemp_department ) position from employee t order by t.emp_id;

EMP_ID ? ? ? ? ? ? ? EMP_NAME ? ? ? ? ? ? EMP_SALARY ? ? ? ? ??EMP_DEPARTMENT ? ? ? TOTAL_SALARY

-------------------- -------------------- ---------------------- ? ? ? ? ??-------------------- ? ? ? ? ? ? ? ? ??---------------------

0001 ? ? ? ? ? ? ? ? ? ??張三 ? ? ? ? ? ? ? ? ? ? ???5000 ? ? ? ? ? ? ? ? ? ? ? ? ? 設計部 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 5000

0002李四4500工程部9000

0003趙飛6000項目部16500

0004韓明4500項目部16500

0005王蘭4500工程部9000

0006李麗6000項目部16500

三、窗口子句

可以使用窗口子句來進一步控制窗口的范圍,包含兩類:rows和range

3.01、rows子句

rows子句以當前記錄為參照,可以向前向后推移,形成新的結果集

語句:select emp_id,emp_name,emp_salary,sum(emp_salary) over(order by emp_id rows between 1 preceding and 1 following) total_salary from employee;

EMP_ID ? ? ? ? ? ? ? EMP_NAME ? ? ? ? ? ? EMP_SALARY ? ? ? ? TOTAL_SALARY

-------------------- -------------------- ---------------------- ? ? ? ? ? ----------------------

0001 ? ? ? ? ? ? ? ? ? ??張三 ? ? ? ? ? ? ? ? ? ? ?? ?5000 ? ? ? ? ? ? ? ? ? ? ? ???9500

0002李四450015500

0003趙飛600015000

0004韓明450015000

0005王蘭450015000

0006李麗600010500

rows子句因為和位置有關,必須使用order by排序,否則報錯

3.02、range子句range子句按照列值進行窗口的進一步限制

語句:select emp_id,emp_name,emp_salary,count(1) over(order by emp_salary range between 300 preceding and 400 following) total_count from employee;

EMP_ID ? ? ? ? ? ? ? EMP_NAME ? ? ? ? ? ? EMP_SALARY ? ? ? ? ? ? TOTAL_COUNT

-------------------- -------------------- ---------------------- ? ? ? ? ? ? ? ----------------------

0005 ? ? ? ? ? ? ? ? 王蘭 ? ? ? ? ? ? ? ? ? ? ? ? ???4500 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 3

0002 ? ? ? ? ? ? ? ? 李四450030004 ? ? ? ? ? ? ? ? 韓明450030001 ? ? ? ? ? ? ? ? 張三500010006 ? ? ? ? ? ? ? ? 李麗600020003 ? ? ? ? ? ? ? ? 趙飛60002

3.03、unbouned和 current row

unbouned表示沒有任何限制,current row代表當前行

四、主要的分析函數

分析函數作用對象為窗口函數所捕獲的記錄集合

4.01?、first_value()函數的使用first_value()函數用于獲取窗口函數所捕獲的記錄集中的第一條記錄,并根據第一條記錄返回返回表達式參數的值

語句:?select * from employee;

EMP_ID ? ? ? ? ? ? EMP_NAME ? ? ?EMP_SALARY ? ?EMP_DEPARTMENT

-------------------- -----------------?---------------------- --------------------

0001 ? ? ? ? ? ? ? ? 張三 ? ? ? ? ? ? ? ? 5000 ? ? ? ? ? ? ? ? ? 設計部

0002 ? ? ? ? ? ? ? ? 李四 ? ? ? ? ? ? ? ? 4500 ? ? ? ? ? ? ? ? ? 工程部

0003 ? ? ? ? ? ? ? ? 趙飛 ? ? ? ? ? ? ? ? 6000 ? ? ? ? ? ? ? ? ? 項目部

0004 ? ? ? ? ? ? ? ? 韓明 ? ? ? ? ? ? ? ? 4500 ? ? ? ? ? ? ? ? ? 項目部

0005 ? ? ? ? ? ? ? ? 王蘭 ? ? ? ? ? ? ? ? 4500 ? ? ? ? ? ? ? ? ? 工程部

0006 ? ? ? ? ? ? ? ? 李麗 ? ? ? ? ? ? ? ? 6000 ? ? ? ? ? ? ? ? ? 項目部

語句:select distinctemp_department,first_value(emp_name) over(partition by emp_department order by emp_salary)minname,

first_value(emp_salary) over(partition by emp_department order by emp_salary)minsalary ?from employee;

EMP_DEPARTMENT ? ? ? MINNAME ? ? ? ? ? ? ?MINSALARY

-------------------- ? ? ? ? ? ? ? ?-------------------- ----------------------

設計部 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 張三 ? ? ? ? ? ? ? ? ? ??5000

項目部韓明4500

工程部李四4500

備注:distinct關鍵字是必要的,查詢每部門工資最少的人 ,人名和工資都要用first_value()函數,每一列都是一個結果集,互不影響,若有一個不加,不加的會顯示所有的值,結果如下:

語句:select distinct emp_department, first_value(emp_name) over(partition by emp_department order by emp_salary) minname,emp_salary from employee;

EMP_DEPARTMENT ? ? ? MINNAME ? ? ? ? ? ? ?EMP_SALARY

-------------------- ? ? ? ? ? ? ??-------------------- ----------------------

工程部 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 李四 ? ? ? ? ? ? ? ?? ? ?4500

設計部張三5000項目部韓明4500

項目部韓明6000

4.02?、last_value()函數的使用

last_value()函數返回窗口中的最后一條記錄的相關信息

語句:select distinct last_value(emp_name) over(partition by emp_department order by emp_salary rows between unbounded preceding and unbounded following) maxname,emp_department,

last_value(emp_salary) over(partition by emp_department order by emp_salaryrows between unbounded preceding and unbounded following) maxsalary ?from employee;

MAXNAME ? ? ? ? ? ? ?EMP_DEPARTMENT ? ? ? MAXSALARY

-------------------- -------------------- ? ? ? ? ? ? ? ? ?----------------------

張三 ? ? ? ? ? ? ? ? ??? ?設計部 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?5000

趙飛項目部6000李四工程部4500

備注:窗口函數中必須使用rows between unbounded preceding and unbounded following,因為默認情況下,order by 窗口為第一條記錄至當前記錄,對于order by 子句,如果沒有顯示指定rows和range子句,則相當于使用了rows between unbounded preceding and current row following或者range between unbounded preceding andcurrent rowfollowing,當排序后存在相同的排名,則所有相同的記錄放到被刷選的窗口中,值不同會放到不同的窗口,未使用的結果如下:

語句:select distinct last_value(emp_name) over(partition by emp_department order by emp_salary) maxname,emp_department,

last_value(emp_salary) over(partition by emp_department order by emp_salary) maxsalary ?from employee;

MAXNAME ? ? ? ? ? ? ?EMP_DEPARTMENT ? ? ? MAXSALARY

-------------------- -------------------- ? ? ? ? ? ? ? ?----------------------

張三 ? ? ? ? ? ? ? ? ? ? ??設計部 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?5000

韓明項目部4500趙飛項目部6000王蘭工程部4500

4.03 、lead()函數的使用

lead()函數對于通過排序之后的窗口集合,lead()函數自當前記錄向下推移,獲得新的記錄

語法:lead(表達式,偏移量,替換值)?其中替換值是當無法獲取新紀錄時,用該值替換

語句:select emp_id,emp_name,emp_salary,emp_department from employee order by emp_id;

EMP_ID ? ? ? ? ? ? ? EMP_NAME ? ? ? ? ? ? EMP_SALARY ? ? ? ? ? ? EMP_DEPARTMENT

-------------------- -------------------- ---------------------- --------------------

0001 ? ? ? ? ? ? ? ? 張三 ? ? ? ? ? ? ? ? 5000 ? ? ? ? ? ? ? ? ? 設計部

0002 ? ? ? ? ? ? ? ? 李四 ? ? ? ? ? ? ? ? 4500 ? ? ? ? ? ? ? ? ? 工程部

0003 ? ? ? ? ? ? ? ? 趙飛 ? ? ? ? ? ? ? ? 6000 ? ? ? ? ? ? ? ? ? 項目部

0004 ? ? ? ? ? ? ? ? 韓明 ? ? ? ? ? ? ? ? 4500 ? ? ? ? ? ? ? ? ? 項目部

0005 ? ? ? ? ? ? ? ? 王蘭 ? ? ? ? ? ? ? ? 4600 ? ? ? ? ? ? ? ? ? 工程部

0006 ? ? ? ? ? ? ? ? 李麗 ? ? ? ? ? ? ? ? 6000 ? ? ? ? ? ? ? ? ? 項目部

語句:select emp_id,emp_name,emp_salary,emp_department,lead(emp_name,1,'無') over(partition by emp_department order by emp_salary) pre_name from employee order by emp_id;

EMP_ID ? ? ? ? ? ? ? EMP_NAME ? ? ? ? ? ? EMP_SALARY ? ? ? ? ? ? EMP_DEPARTMENT ? ? ? PRE_NAME

-------------------- -------------------- ---------------------- -------------------- --------------------

0001 ? ? ? ? ? ? ? ? 張三 ? ? ? ? ? ? ? ? 5000 ? ? ? ? ? ? ? ? ? 設計部 ? ? ? ? ? ? ? 無

0002 ? ? ? ? ? ? ? ? 李四 ? ? ? ? ? ? ? ? 4500 ? ? ? ? ? ? ? ? ? 工程部 ? ? ? ? ? ? ? 王蘭

0003 ? ? ? ? ? ? ? ? 趙飛 ? ? ? ? ? ? ? ? 6000 ? ? ? ? ? ? ? ? ? 項目部 ? ? ? ? ? ? ? 無

0004 ? ? ? ? ? ? ? ? 韓明 ? ? ? ? ? ? ? ? 4500 ? ? ? ? ? ? ? ? ? 項目部 ? ? ? ? ? ? ? 李麗

0005 ? ? ? ? ? ? ? ? 王蘭 ? ? ? ? ? ? ? ? 4600 ? ? ? ? ? ? ? ? ? 工程部 ? ? ? ? ? ? ? 無0006 ? ? ? ? ? ? ? ? 李麗 ? ? ? ? ? ? ? ? 6000 ? ? ? ? ? ? ? ? ? 項目部 ? ? ? ? ? ? ? 趙飛

4.04 、lag()函數的使用

lag()函數與lead()函數具有相同的語法規則,在排序之后,lag()函數自當前記錄向上搜索

語法:select emp_id,emp_name,emp_salary,emp_department,lag(emp_name,1,'無') over(partition by emp_department order by emp_salary) pre_name from employee order by emp_id;

EMP_ID ? ? ? ? ? ? ? EMP_NAME ? ? ? ? ? ? EMP_SALARY ? ? ? ? ? ? EMP_DEPARTMENT ? ? ? PRE_NAME

-------------------- -------------------- ---------------------- -------------------- --------------------

0001 ? ? ? ? ? ? ? ? 張三 ? ? ? ? ? ? ? ? 5000 ? ? ? ? ? ? ? ? ? 設計部 ? ? ? ? ? ? ? 無

0002 ? ? ? ? ? ? ? ? 李四 ? ? ? ? ? ? ? ? 4500 ? ? ? ? ? ? ? ? ? 工程部 ? ? ? ? ? ? ? 無

0003 ? ? ? ? ? ? ? ? 趙飛 ? ? ? ? ? ? ? ? 6000 ? ? ? ? ? ? ? ? ? 項目部 ? ? ? ? ? ? ? 李麗

0004 ? ? ? ? ? ? ? ? 韓明 ? ? ? ? ? ? ? ? 4500 ? ? ? ? ? ? ? ? ? 項目部 ? ? ? ? ? ? ? 無

0005 ? ? ? ? ? ? ? ? 王蘭 ? ? ? ? ? ? ? ? 4600 ? ? ? ? ? ? ? ? ? 工程部 ? ? ? ? ? ? ? 李四

0006 ? ? ? ? ? ? ? ? 李麗 ? ? ? ? ? ? ? ? 6000 ? ? ? ? ? ? ? ? ? 項目部 ? ? ? ? ? ? ? 韓明

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,677評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,643評論 2 380

推薦閱讀更多精彩內容