高級函數(shù)_分析函數(shù)與窗口函數(shù)

高級函數(shù)_分析函數(shù)與窗口函數(shù)

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

一、分析函數(shù)

1.01、排名

分析函數(shù)中的排名函數(shù)可以針對窗口中的記錄生成排序序號,常用的排名函數(shù)有: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()函數(shù)對于相同排名的記錄,會返回相同的排序序號,當出現(xiàn)多個排名?相同的記錄時,下一排名序號,將根據(jù)前一排名個數(shù)進行跳躍,如里面沒有出現(xiàn)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()函數(shù)對于相同排名的記錄,會返回相同的排序序號,當出現(xiàn)多個排名?相同的記錄時,不會進行跳躍

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

EMP_NAME ? ? ? ? ? ? ??POSITION

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

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

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

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

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

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

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

二、分區(qū)窗口

利用partition by 可以指定?分區(qū)窗口

語句:?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

分區(qū)內可以求和

語句: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代表當前行

四、主要的分析函數(shù)

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

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

語句:?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()函數(shù),每一列都是一個結果集,互不影響,若有一個不加,不加的會顯示所有的值,結果如下:

語句: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()函數(shù)的使用

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

語句: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

備注:窗口函數(shù)中必須使用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()函數(shù)的使用

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

語法: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()函數(shù)的使用

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

語法: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 ? ? ? ? ? ? ? ? ? 項目部 ? ? ? ? ? ? ? 韓明

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容