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/
