(一)分析函數語法
function_name(<argument>,<argument>...) over(<partition by clause><order by clause> <windowing_clause>);
function_name:函數名稱,如count(),sum(),avg(),max(),min()等
argument : 參數
over() : 開窗函數
partition_clause:分區(分組)子句
order by clause:排序字句,數據記錄排序,累計計算
windowing clause:開窗子句,定義分析函數在操作行的集合。分析函數有三種:rows、range、specifying。
(二)分析函數使用匯總
(2.1)count() over():統計分區各組中的行數,partition by可選,order by可選。
例子1:統計總人數
SQL> SELECT ename,job,COUNT(*) OVER() FROM emp; --總計數
例子2:按照sal排序,統計總人數
SELECT ename,job,sal,COUNT(*) OVER(ORDER BY sal) FROM emp; --按照薪資遞加計數
例子3:統計各個部門的總人數
SELECT ename,job,sal,deptno,COUNT(*) OVER(PARTITION BY deptno) FROM emp; --分組計數,統計各個部門的人數
例子4:對部門分組,對各個部門按照薪資排序並計數
SELECT ename,job,deptno,sal,COUNT(*) OVER(PARTITION BY deptno ORDER BY sal) FROM emp; --按照各個部門的薪資水平排序
(2.2)sum() over():記錄分區中的總和,partition by可選,order by可選
例子1:求出所有部門的薪資總和
SELECT ename,job,sal,hiredate,SUM(sal) OVER() FROM emp;
例子2:求出各個部門薪資的累計值,按部門累計
SELECT ename,job,sal,hiredate,SUM(sal) OVER(ORDER BY deptno) FROM emp;
例子3:求出各自部門薪資的總和
SELECT ename,job,deptno,sal,hiredate,SUM(sal) OVER(PARTITION BY deptno) FROM emp
例子4:求出各部門薪資累計值
SELECT ename,job,deptno,sal,hiredate,SUM(sal) OVER(PARTITION BY deptno ORDER BY sal) FROM emp;
(2.3)avg() over():記錄分區中的平均值,partition by可選,order by可選
例子1:求出所有人的平均薪資
SELECT ename,sal,hiredate,AVG(sal) OVER() FROM emp;
例子2:求出部門的累計薪資。
SELECT ename,deptno,sal,hiredate,AVG(sal) OVER(ORDER BY deptno) FROM emp;
圖中紅色代表10號部門人員的平均薪資,
藍色代表10號部門與20號部門人員的平均薪資,
紫色代表10號部門與20號部門與30號部門人員的平均薪資。
例子3.求出各個部門的平均薪資
SELECT ename,deptno,sal,hiredate,AVG(sal) OVER(PARTITION BY deptno) FROM emp;
例子4:求出各個部門的平均累計薪資
SELECT ename,deptno,sal,hiredate,AVG(sal) OVER(PARTITION BY deptno ORDER BY sal) FROM emp;
(2.4)min() avg():統計分組中的最小值,partition by可選,order by可選
例子1:求所有人中薪資最小值
SELECT ename,sal,hiredate,MIN(sal) OVER() FROM emp;
例子2:求出按部門累計的最小薪資
SELECT ename,deptno,sal,hiredate,MIN(sal) OVER(ORDER BY deptno) FROM emp;
圖中紅圈是10號部門的最低薪資,藍圈是10號部門與20號部門的最低薪資,紫圈是10號部門、20號部門、30號部門的最低薪資。
例子3:求出各個部門的最低薪資
SELECT ename,deptno,sal,hiredate,MIN(sal) OVER(PARTITION BY deptno) FROM emp;
例子4:按照部門求出各自部門的最小薪資,並按照部門分組后再按照薪資排序
SELECT ename,deptno,sal,hiredate,MIN(sal) OVER(PARTITION BY deptno ORDER BY sal) FROM emp;
(2.5)max() avg():統計分組中的最大值,partition by可選,order by可選。用法與上面的min() over()相似。
(2.6)row_number() over():排序,排序序號無重復值,partition by可選,order by必選
例子1:按照薪資水平從高到低輸出所有人的信息
SELECT ename,deptno,sal,hiredate,row_number() OVER(ORDER BY sal DESC) FROM emp;
例子2:先按部門分組,再按照薪資水平從高到低輸出所有人的信息
SELECT ename,deptno,sal,hiredate,row_number() OVER(PARTITION BY deptno ORDER BY sal DESC) FROM emp;
例子2.1:求出各個部門前2名薪資最高的人員信息
SELECT * FROM (SELECT ENAME, DEPTNO, SAL, HIREDATE, ROW_NUMBER() OVER(PARTITION BY DEPTNO ORDER BY SAL DESC) RN FROM EMP) WHERE RN < 3;
(2.7)rank() over():跳躍排序,排序序號會有重復,partition by可選,order by必選
例子1:先按照部門降序,再按照薪資降序排序
SELECT ename,deptno,sal,hiredate,RANK() OVER(ORDER BY deptno DESC,sal DESC) FROM emp;
例子2:先按照部門分區(分組),再按照薪資升序排序
SELECT ename,deptno,sal,hiredate,RANK() OVER(PARTITION BY deptno ORDER BY sal) FROM emp;
(2.8)dense_rank() over():連續排序,排序序號會有重復,partition by可選,order by必選
例子1:先按部門排序,再只能找工資排序
SELECT ename,deptno,sal,hiredate,dense_rank() OVER(ORDER BY deptno DESC,sal DESC) FROM emp;
例子2:先按照部門分組,再按照薪資排序
SELECT ename,deptno,sal,hiredate,dense_rank() OVER(PARTITION BY deptno ORDER BY sal) FROM emp;
(2.9)ntile(n) over():將記錄平均分成n份,多出的按照次序分給前面的組。partition by可選,order by必選。
例子1:將emp表信息按照薪資從低到高分成4份
例子2:先按照部門分組,再將每個部門的數據按照薪資從低到高分成4份。
SELECT ename,deptno,sal,hiredate,NTILE(4) OVER(PARTITION BY deptno ORDER BY sal) FROM emp;
(2.10)first_value() over():取出分區中第一條記錄字段的值。partition by可選 ,order by可選。
last_value() over() :取出分區中最后一條記錄字段的值。partition by可選,order by可選。
(2.11)lag() over():取出前n行數據,加到當前行作為一個新的列。partition by可選,order by必選。
語法為:lag(field,num,defaultValue) field為要查找的字段,num代表往前查找num行的數據,defaultValue代表沒有符合條件的默認值。通過該函數可以去除前n行的數據放入到當前行的新列中。
例子1:將前一個用戶的薪資作為新的列forward_sal加入到當前用戶信息中。
SELECT ename,deptno,sal,hiredate,LAG(sal,1,0) OVER(ORDER BY sal) forward_sal FROM emp;
例子2:按照部門分組,再將前一個用戶的薪資作為新的列forward_sal加入到當前用戶信息中
SELECT ename,deptno,sal,hiredate,LAG(sal,1,0) OVER(PARTITION BY deptno ORDER BY sal) forward_sal FROM emp;
(2.12)lead() over():取出后n行數據,加到當前行作為一個新的列。partition by可選,order by必選。
例子1:按照sal從小到大排序,取出后一行的sal數據添加到當前行,作為一個新的列
SELECT ename,deptno,sal,hiredate,LEAD(sal,1,0) OVER(ORDER BY sal) FROM emp;
【完】