1.一、兩個order by的執行時機
分析函數是在整個sql查詢結束後(sql語句中的order by的執行比較特殊)再進行的操做, 也就是說sql語句中的order by也會影響分析函數的執行結果:html
a) 二者一致:若是sql語句中的order by知足分析函數分析時要求的排序,那麼sql語句中的排序將先執行,分析函數在分析時就沒必要再排序;
b) 二者不一致:若是sql語句中的order by不知足分析函數分析時要求的排序,那麼sql語句中的排序將最後在分析函數分析結束後執行排序。sql
1.二、分析函數中的分組/排序/窗口
分析函數包含三個分析子句:分組(partition by), 排序(order by), 窗口(rows)
窗口就是分析函數分析時要處理的數據範圍,就拿sum來講,它是sum窗口中的記錄而不是整個分組中的記錄,所以咱們在想獲得某個欄位的累計值時,咱們須要把窗口指定到該分組中的第一行數據到當前行, 若是你指定該窗口從該分組中的第一行到最後一行,那麼該組中的每個sum值都會同樣,即整個組的總和。函數
窗口子句在這裏我只說rows方式的窗口,range方式和滑動窗口也不提。
窗口子句中咱們常常用到指定第一行,當前行,最後一行這樣的三個屬性。
第一行是 unbounded preceding,
當前行是 current row,
最後一行是 unbounded following,
窗口子句不能單獨出現,必須有order by子句時才能出現,如:spa
last_value(sal) over(partition by deptno order by sal rows between unbounded preceding and unbounded following)
以上示例指定窗口爲整個分組。而出現order by子句的時候,不必定要有窗口子句,但效果會很不同,此時的窗口默認是當前組的第一行到當前行!3d
當省略窗口子句時:
a) 若是存在order by則默認的窗口是unbounded preceding and current row --當前組的第一行到當前行
b) 若是同時省略order by則默認的窗口是unbounded preceding and unbounded following --整個組htm
若是省略分組,則把所有記錄當成一個組:
a) 若是存在order by則默認窗口是unbounded preceding and current row --當前組的第一行到當前行
b) 若是這時省略order by則窗口默認爲unbounded preceding and unbounded following --整個組blog
1.三、幫助理解over()的實例排序
例1:關注點:sql無排序,over()排序子句省略get
SELECT DEPTNO, EMPNO, ENAME, SAL, LAST_VALUE(SAL) OVER(PARTITION BY DEPTNO) FROM EMP;
運行結果:it
例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;
運行結果: