Oracle常用函數--over()開窗函數


什么是分析函數(partition by):

  分析函數是Oracle專門用於解決復雜報表統計需求的函數,它可以在數據中進行分組,然后計算基於組的某種統計值,並且每一組的每一行都可以返回一個統計值。

分析函數和聚合函數的不同之處是什么?

  普通的聚合函數用group by分組,每個分組返回一個統計值,只有一行,而分析函數采用partition by分組,每組中包含多個值。

  開窗函數 其實就是group by的另一種。它與group by的區別在於開窗函數可以在分組列中再排序,其實就是加了一列隱藏列,可以在group by中再分組的意思.

關於開窗函數(over()):

  開窗函數指定了分析函數中的分組的大小。

  分析函數帶有一個開窗函數over(),包含三個分析子句:分組(partition by), 排序(order by), 窗口(rows) ,這些就是窗口的規則。

  他們的使用形式如下:over(partition by xxx order by yyy rows between zzz)。

  注意:窗口子句不能單獨出現,必須有order by子句時才能出現。

兩個order by的執行時機:

  分析函數(以及與其配合的開窗函數over())是在整個sql查詢結束后(sql語句中的order by的執行比較特殊)再進行的操作, 也就是說sql語句中的order by也會影響分析函數的執行結果:

  a) 兩者一致:如果sql語句中的order by滿足與分析函數配合的開窗函數over()分析時要求的排序,即sql語句中的order by子句里的內容和開窗函數over()中的order by子句里的內容一樣,那么sql語句中的排序將先執行,分析函數在分析時就不必再排序;

  b) 兩者不一致:如果sql語句中的order by不滿足與分析函數配合的開窗函數over()分析時要求的排序,即sql語句中的order by子句里的內容和開窗函數over()中的order by子句里的內容不一樣,那么sql語句中的排序將最后在分析函數分析結束后執行排序。

開窗函數的例子;

  開窗函數指定了分析函數工作的數據窗口大小,這個數據窗口大小可能會隨着行的變化而變化,舉例如下:

  1、over(order by salary) 按照salary排序進行累計,order by是個默認的開窗函數。

SELECT EMPLOYEE_ID,
       SALARY,
       MANAGER_ID,
       DEPARTMENT_ID,
       SUM(SALARY) OVER(ORDER BY SALARY) DD
  FROM INFA_TEST.EMPLOYEES EMP
 ORDER BY SALARY

    功能:按salary升序排序,統計小於等於當前salary的salary總和。

    返回結果:

ROWNUM EMPLOYEE_ID  SALARY  MANAGER_ID  DEPARTMENT_ID  DD 備注
1 132  2100 121 50 2100  
2 128  2200 120 50 6500 2200+2200+2100
3 136 2200 122 50 6500 2200+2200+2100
4 127 2400 120 50 11300 6500+2400+2400
5 135 2400 122 50 11300 6500+2400+2400
6 119 2500 114 30 26300 11300+2500*5
7 140  2500 123 50 26300 11300+2500*5
8 144 2500 124 50 26300 11300+2500*5
9 191 2500 122 50 26300 11300+2500*5
10 182 2500 120 50 26300 11300+2500*5

 

    注意 SALARY為2200、2400和2500行的DD值,

    2、over(partition by DEPARTMENT_ID)按照部門分區。

SELECT EMPLOYEE_ID,
       SALARY,
       MANAGER_ID,
       DEPARTMENT_ID,
       SUM(SALARY) OVER(PARTITION BY DEPARTMENT_ID) DD
  FROM INFA_TEST.EMPLOYEES EMP
 ORDER BY DEPARTMENT_ID

    功能:按DEPARTMENT_ID分區,匯總各個部門的SALARY總和。

    返回結果:

ROWNUM EMPLOYEE_ID  SALARY  MANAGER_ID  DEPARTMENT_ID DD 備注
1 200 4400 101 10 4400  
2 201 13000 100 20 19000 13000+6000
3 202 6000 201 20 19000 13000+6000
4 114 11000 100 30 24900 11000+3100+2900+2500+2600+2800
5 115 3100 114 30 24900 11000+3100+2900+2500+2600+2800
6 116 2900 114 30 24900 11000+3100+2900+2500+2600+2800
7 119 2500 114 30 24900 11000+3100+2900+2500+2600+2800
8 118 2600 114 30 24900 11000+3100+2900+2500+2600+2800
9 117 2800 114 30 24900 11000+3100+2900+2500+2600+2800

    注意 DEPARTMENT_ID為20,30的DD值

    3、over(partition by DEPARTMENT_ID order by SALARY)按照部門分區。

SELECT EMPLOYEE_ID,
       SALARY,
       MANAGER_ID,
       DEPARTMENT_ID,
       SUM(SALARY) OVER(PARTITION BY DEPARTMENT_ID ORDER BY SALARY) DD
  FROM INFA_TEST.EMPLOYEES EMP
 ORDER BY DEPARTMENT_ID

   功能:按DEPARTMENT_ID分區,按SALARY升序排序,統計各個部門內部小於當前SALARY的和。

    返回結果:

ROWNUM EMPLOYEE_ID SALARY MANAGER_ID DEPARTMENT_ID DD 備注
1 200 4400 101 10 4400 DEPARTMENT_ID=10的SALARY
2 201 13000 100 20 6000 DEPARTMENT_ID=20的SALARY排序並求和
3 202 6000 201 20 19000 DEPARTMENT_ID=20的SALARY排序並求和:6000+13000
4 114 11000 100 30 2500 DEPARTMENT_ID=30的SALARY排序並求和
5 115 3100 114 30 5100 DEPARTMENT_ID=30的SALARY排序並求和:2500+2600
6 116 2900 114 30 7900 DEPARTMENT_ID=30的SALARY排序並求和:5100+2800
7 119 2500 114 30 10800 DEPARTMENT_ID=30的SALARY排序並求和:7900+2900
8 118 2600 114 30 13900 DEPARTMENT_ID=30的SALARY排序並求和:10800+3100
9 117 2800 114 30 24900 DEPARTMENT_ID=30的SALARY排序並求和:13900+11000

 注意 DEPARTMENT_ID為20、30的DD值和2中的區別   

    4、over(order by salary range between 50 preceding and 150 following)

SELECT EMPNO,
       SAL,
       MGR,
       DEPTNO,
       SUM(SAL) OVER(PARTITION BY DEPTNO ORDER BY SAL RANGE BETWEEN 0 PRECEDING AND 100 FOLLOWING) DD
  FROM EMP;

功能:按DEPTNO分區,按SAL升序排序,匯總當前SAL到比當前SAL大100之間的SAL總和。

    返回結果:

ROWNUM EMPNO SAL MGR DEPTNO DD 備注
1 7934 1300 7782 10 1300  
2 7782 2450 7839 10 2450  
3 7839 5000   10 5000  
4 7369 800 7902 20 800  
5 7566 2975 7839 20 5975 3000在2975和(2975+100)之間,故求2975與3000的和
6 7902 3000 7566 20 3000  
7 7900 950 7698 30 950  
8 7521 1250 7698 30 2500 1250在1250和(1250+100)之間,故求1250和1250的和
9 7654 1250 7698 30 2500  
10 7844 1500 7698 30 3100 1600在1500和(1500+100)之間,故求1500和1600的和
11 7499 1600 7698 30 1600  
12 7698 2850 7839 30 2850  

  解釋:返回前置行和當前行SAL相等,后續行比他大100的記錄,在SAL列上求和。

 上下邊界沒有限制:OVER (PARTITION BY DEPTNO ORDER BY SAL RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)      

SELECT EMPNO,
       SAL,
       MGR,
       DEPTNO,
       SUM(SAL) OVER(PARTITION BY DEPTNO ORDER BY SAL RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) DD
  FROM EMP;
ROWNUM EMPNO SAL MGR DEPTNO DD 備注
1 7934 1300 7782 10 8750 1300+2450+5000
2 7782 2450 7839 10 8750 1300+2450+5000
3 7839 5000   10 8750 1300+2450+5000
4 7369 800 7902 20 6775 800+2975+3000
5 7566 2975 7839 20 6775 800+2975+3000
6 7902 3000 7566 20 6775 800+2975+3000
7 7900 950 7698 30 9400 950+1250+1250+1500+1600+2850
8 7521 1250 7698 30 9400 950+1250+1250+1500+1600+2850
9 7654 1250 7698 30 9400 950+1250+1250+1500+1600+2850
10 7844 1500 7698 30 9400 950+1250+1250+1500+1600+2850
11 7499 1600 7698 30 9400 950+1250+1250+1500+1600+2850
12 7698 2850 7839 30 9400 950+1250+1250+1500+1600+2850

 

    解釋:返回以DEPTNO分組的SAL列上求和

5、over(order by salary rows between 1 preceding and 2 following)-- 每行對應的數據窗口是之前行幅度值不超過1,之后行幅度值不超過2

1 SELECT EMPNO,
2        SAL,
3        MGR,
4        DEPTNO,
5        SUM(SAL) OVER(PARTITION BY DEPTNO ORDER BY SAL ROWS BETWEEN 1 PRECEDING AND 2 FOLLOWING) DD
6   FROM EMP;

    返回結果

ROWNUM EMPNO SAL MGR DEPTNO DD 備注
1 7934 1300 7782 10 8750 本行和后兩行SAL的和:1300+2450+5000
2 7782 2450 7839 10 8750 本行和前一行和后一行SAL的和:2450+1300+5000
3 7839 5000   10 7450 本行和前一行SAL的和:5000+2450
4 7369 800 7902 20 6775 本行和后兩行SAL的和:800+2975+3000
5 7566 2975 7839 20 6775 本行和前一行和后一行SAL的和:2975+800+3000
6 7902 3000 7566 20 5975 本行和前一行SAL的和:3000+2975
7 7900 950 7698 30 3450 本行和后兩行SAL的和:950+1250+1250
8 7521 1250 7698 30 4950 本行和前一行和后兩行SAL的和:1250+950+1250+1500
9 7654 1250 7698 30 5600 本行和前一行和后兩行SAL的和:1250+1250+1500+1600
10 7844 1500 7698 30 7200 本行和前一行和后兩行SAL的和:1500+1250+1600+2850
11 7499 1600 7698 30 5950 本行和前一行和后一行SAL的和:1600+1500+2850
12 7698 2850 7839 30 4450 本行和前一行SAL的和:2850+1600

解釋:如果分組后本行前一行或者后一行沒有數據了,就不進行求和了.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM