二、理解over()函數


1.1、兩個order by的執行時機
分析函數是在整個sql查詢結束后(sql語句中的order by的執行比較特殊)再進行的操作, 也就是說sql語句中的order by也會影響分析函數的執行結果:

a) 兩者一致:如果sql語句中的order by滿足分析函數分析時要求的排序,那么sql語句中的排序將先執行,分析函數在分析時就不必再排序
b) 兩者不一致:如果sql語句中的order by不滿足分析函數分析時要求的排序,那么sql語句中的排序將最后在分析函數分析結束后執行排序

           

1.2、分析函數中的分組/排序/窗口
      分析函數包含三個分析子句:分組(partition by), 排序(order by), 窗口(rows)
      窗口就是分析函數分析時要處理的數據范圍,就拿sum來說,它是sum窗口中的記錄而不是整個分組中的記錄,因此我們在想得到某個欄位的累計值時,我們需要把窗口指定到該分組中的第一行數據到當前行, 如果你指定該窗口從該分組中的第一行到最后一行,那么該組中的每一個sum值都會一樣,即整個組的總和。

      窗口子句在這里我只說rows方式的窗口,range方式和滑動窗口也不提。
      窗口子句中我們經常用到指定第一行,當前行,最后一行這樣的三個屬性。
第一行是 unbounded preceding,
當前行是 current row,
最后一行是 unbounded following,
窗口子句不能單獨出現,必須有order by子句時才能出現,如:

last_value(sal) over(partition by deptno 
order by sal
rows between unbounded preceding and unbounded following)

以上示例指定窗口為整個分組。而出現order by子句的時候,不一定要有窗口子句,但效果會很不一樣,此時的窗口默認是當前組的第一行到當前行!

 

當省略窗口子句時:
a) 如果存在order by則默認的窗口是unbounded preceding and current row  --當前組的第一行到當前行
b) 如果同時省略order by則默認的窗口是unbounded preceding and unbounded following  --整個組

             
如果省略分組,則把全部記錄當成一個組:
a) 如果存在order by則默認窗口是unbounded preceding and current row   --當前組的第一行到當前行
b) 如果這時省略order by則窗口默認為unbounded preceding and unbounded following  --整個組

     

1.3、幫助理解over()的實例

例1:關注點:sql無排序,over()排序子句省略

SELECT DEPTNO, EMPNO, ENAME, SAL, 
LAST_VALUE(SAL) OVER(PARTITION BY DEPTNO)
FROM EMP;

運行結果:

 

       

例2:關注點:sql無排序,over()排序子句有,窗口省略

 

SELECT DEPTNO,
EMPNO,
ENAME,
SAL,
LAST_VALUE(SAL) OVER(PARTITION BY DEPTNO
ORDER BY SAL DESC)
FROM EMP;

運行結果:

 

                  
例3:關注點:sql無排序,over()排序子句有,窗口也有,窗口特意強調全組數據

 

SELECT DEPTNO,
EMPNO,
ENAME,
SAL,
LAST_VALUE(SAL)
OVER(PARTITION BY DEPTNO
ORDER BY SAL
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) MAX_SAL
FROM EMP;

運行結果:

 

     
例4:關注點:sql有排序(正序),over()排序子句無,先做sql排序再進行分析函數運算

 

SELECT DEPTNO,
MGR,
ENAME,
SAL,
HIREDATE,
LAST_VALUE(SAL) OVER(PARTITION BY DEPTNO) LAST_VALUE
FROM EMP
WHERE DEPTNO = 30
ORDER BY DEPTNO, MGR;

運行結果:

 

 



例5:關注點:sql有排序(倒序),over()排序子句無,先做sql排序再進行分析函數運算

 

SELECT DEPTNO,
MGR,
ENAME,
SAL,
HIREDATE,
LAST_VALUE(SAL) OVER(PARTITION BY DEPTNO) LAST_VALUE
FROM EMP
WHERE DEPTNO = 30
ORDER BY DEPTNO, MGR DESC;

運行結果:

                

例6:關注點:sql有排序(倒序),over()排序子句有,窗口子句無,此時的運算是:sql先選數據但是不排序,而后排序子句先排序並進行分析函數處理(窗口默認為第一行到當前行),最后再進行sql排序

 

 

SELECT DEPTNO,
MGR,
ENAME,
SAL,
HIREDATE,
MIN(SAL) OVER(PARTITION BY DEPTNO ORDER BY SAL ASC) LAST_VALUE
FROM EMP
WHERE DEPTNO = 30
ORDER BY DEPTNO, MGR DESC;

運行結果:

 

SELECT DEPTNO,
MGR,
ENAME,
SAL,
HIREDATE,
MIN(SAL) OVER(PARTITION BY DEPTNO ORDER BY SAL DESC) LAST_VALUE
FROM EMP
WHERE DEPTNO = 30
ORDER BY DEPTNO, MGR DESC;

運行結果:

              

---------------------------------------------------------------------------------------
Blog:http://www.cnblogs.com/linjiqin/
J2EE、Android、Linux、Oracle QQ交流群:142463980、158560018(滿)

題外話:
本人來自鐵觀音的發源地——泉州安溪,正宗安溪鐵觀音,有需要的友友歡迎加我Q:416501600。
茶葉淘寶店:http://shop61968332.taobao.com/


免責聲明!

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



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