oracle的LAG和LEAD分析函數

Lag和Lead函數可以在一次查詢中取出同一字段的前N行的數據和後N行的值。這種操作可以使用對相同表的表連接來實現,不過使用LAG和LEAD有更高的效率。

lag的語法如下:
lead的語法如下:
lead 和lag 的語法類似以下以lag爲例進行講解!
lag(exp_str,offset,defval) over()
exp_str 是要做對比的字段
offset 是exp_str字段的偏移量 比如說 offset 爲2 則 拿exp_str的第一行和第三行對比,第二行和第四行,依次類推,offset的默認值爲1!
defval是當該函數無值可用的情況下返回的值。Lead函數的用法類似。
以下是lag和lead的例子
SCOTT@yangdb> set pagesize 10000
SCOTT@yangdb> select ename,job,sal ,lag(sal) over(order by sal) last_sal from emp;
ENAME      JOB              SAL   LAST_SAL
---------- --------- ---------- ----------
SMITH      CLERK            800       --此時沒有設置default 值 則爲空值
JAMES      CLERK            950        800
ADAMS      CLERK           1100        950
WARD       SALESMAN        1250       1100
MARTIN     SALESMAN        1250       1250
MILLER     CLERK           1300       1250
TURNER     SALESMAN        1500       1300
ALLEN      SALESMAN        1600       1500
CLARK      MANAGER         2450       1600
BLAKE      MANAGER         2850       2450
JONES      MANAGER         2975       2850
SCOTT      ANALYST         3000       2975
FORD       ANALYST         3000       3000
KING       PRESIDENT       5000       3000
14 rows selected.
設置了default 值之後 第一行對應的值 爲500
SCOTT@yangdb> select ename,job,sal ,lag(sal,1,500) over(order by sal) last_sal from emp;
ENAME      JOB              SAL   LAST_SAL
---------- --------- ---------- ----------
SMITH      CLERK            800        500
JAMES      CLERK            950        800
ADAMS      CLERK           1100        950
WARD       SALESMAN        1250       1100
MARTIN     SALESMAN        1250       1250
MILLER      CLERK           1300       1250
TURNER     SALESMAN        1500       1300
ALLEN      SALESMAN        1600       1500
CLARK      MANAGER         2450       1600
BLAKE      MANAGER         2850       2450
JONES      MANAGER         2975       2850
SCOTT      ANALYST         3000       2975
FORD       ANALYST         3000       3000
KING       PRESIDENT       5000       3000
14 rows selected.
指定offset的值爲2時
SCOTT@yangdb> select ename,job,sal ,lag(sal,2) over(order by sal) last_sal from emp;
ENAME      JOB              SAL   LAST_SAL
---------- --------- ---------- ----------
SMITH      CLERK            800
JAMES      CLERK            950
ADAMS      CLERK           1100        800
WARD       SALESMAN        1250        950
MARTIN     SALESMAN        1250       1100
MILLER     CLERK           1300       1250
TURNER     SALESMAN        1500       1250
ALLEN      SALESMAN        1600       1300
CLARK      MANAGER         2450       1500
BLAKE      MANAGER         2850       1600
JONES      MANAGER         2975       2450
SCOTT      ANALYST         3000       2850
FORD       ANALYST         3000       2975
KING       PRESIDENT       5000       3000
14 rows selected.
offset的值爲3
SCOTT@yangdb> select ename,job,sal ,lag(sal,3) over(order by sal) last_sal from emp;
ENAME      JOB              SAL   LAST_SAL
---------- --------- ---------- ----------
SMITH      CLERK            800
JAMES      CLERK            950
ADAMS      CLERK           1100
WARD       SALESMAN        1250        800
MARTIN     SALESMAN        1250        950
MILLER     CLERK           1300       1100
TURNER     SALESMAN        1500       1250
ALLEN      SALESMAN        1600       1250
CLARK      MANAGER         2450       1300
BLAKE      MANAGER         2850       1500
JONES      MANAGER         2975       1600
SCOTT      ANALYST         3000       2450
FORD       ANALYST         3000       2850
KING       PRESIDENT       5000       2975
14 rows selected.
使用lead分析函數
SCOTT@yangdb> select ename,job,sal ,lead(sal) over(order by sal) last_sal from emp;
ENAME      JOB              SAL   LAST_SAL
---------- --------- ---------- ----------
SMITH      CLERK            800        950
JAMES      CLERK            950       1100
ADAMS      CLERK           1100       1250
WARD       SALESMAN        1250       1250
MARTIN     SALESMAN        1250       1300
MILLER     CLERK           1300       1500
TURNER     SALESMAN        1500       1600
ALLEN      SALESMAN        1600       2450
CLARK      MANAGER         2450       2850
BLAKE      MANAGER         2850       2975
JONES      MANAGER         2975       3000
SCOTT      ANALYST         3000       3000
FORD       ANALYST         3000       5000
KING       PRESIDENT       5000
14 rows selected.
SCOTT@yangdb> select ename,job,sal ,lead(sal,1) over(order by sal) last_sal from emp;
ENAME      JOB              SAL   LAST_SAL
---------- --------- ---------- ----------
SMITH      CLERK            800        950
JAMES      CLERK            950       1100
ADAMS      CLERK           1100       1250
WARD       SALESMAN        1250       1250
MARTIN     SALESMAN        1250       1300
MILLER     CLERK           1300       1500
TURNER     SALESMAN        1500       1600
ALLEN      SALESMAN        1600       2450
CLARK      MANAGER         2450       2850
BLAKE      MANAGER         2850       2975
JONES      MANAGER         2975       3000
SCOTT      ANALYST         3000       3000
FORD       ANALYST         3000       5000
KING       PRESIDENT       5000
14 rows selected.
SCOTT@yangdb> select ename,job,sal ,lead(sal,2) over(order by sal) last_sal from emp;
ENAME      JOB              SAL   LAST_SAL
---------- --------- ---------- ----------
SMITH      CLERK            800       1100
JAMES      CLERK            950       1250
ADAMS      CLERK           1100       1250
WARD       SALESMAN        1250       1300
MARTIN     SALESMAN        1250       1500
MILLER     CLERK           1300       1600
TURNER     SALESMAN        1500       2450
ALLEN      SALESMAN        1600       2850
CLARK      MANAGER         2450       2975
BLAKE      MANAGER         2850       3000
JONES      MANAGER         2975       3000
SCOTT      ANALYST         3000       5000
FORD       ANALYST         3000
KING       PRESIDENT       5000
SCOTT@yangdb> select ename,job,sal ,lead(sal,3) over(order by sal) last_sal from emp;
ENAME      JOB              SAL   LAST_SAL
---------- --------- ---------- ----------
SMITH      CLERK            800       1250
JAMES      CLERK            950       1250
ADAMS      CLERK           1100       1300
WARD       SALESMAN        1250       1500
MARTIN     SALESMAN        1250       1600
MILLER     CLERK           1300       2450
TURNER     SALESMAN        1500       2850
ALLEN      SALESMAN        1600       2975
CLARK      MANAGER         2450       3000
BLAKE      MANAGER         2850       3000
JONES      MANAGER         2975       5000
SCOTT      ANALYST         3000
FORD       ANALYST         3000
KING       PRESIDENT       5000
14 rows selected.
lead 的offset N 是以記錄的第N行和第一做對比注意末尾的 null 值!

Lead和Lag函數也可以使用分組,以下是使用 job 分組的例子:

SCOTT@yangdb> select ename,job,sal ,lead(sal,1) over(partition by job order by sal) last_sal from emp;
ENAME      JOB              SAL   LAST_SAL
---------- --------- ---------- ----------
FORD       ANALYST         3000       3000
SCOTT      ANALYST         3000
SMITH      CLERK            800        950
JAMES      CLERK            950       1100
ADAMS      CLERK           1100       1300
MILLER     CLERK           1300
CLARK      MANAGER         2450       2850
BLAKE      MANAGER         2850       2975
JONES      MANAGER         2975
KING       PRESIDENT       5000
MARTIN     SALESMAN        1250       1250
WARD       SALESMAN        1250       1500
TURNER     SALESMAN        1500       1600
ALLEN      SALESMAN        1600
14 rows selected.
SCOTT@yangdb> select ename,job,sal ,lag(sal,1) over(partition by job order by sal) last_sal from emp;
ENAME      JOB              SAL   LAST_SAL
---------- --------- ---------- ----------
FORD       ANALYST         3000
SCOTT      ANALYST         3000       3000
SMITH      CLERK            800
JAMES      CLERK            950        800
ADAMS      CLERK           1100        950
MILLER     CLERK           1300       1100
CLARK      MANAGER         2450
BLAKE      MANAGER         2850       2450
JONES      MANAGER         2975       2850
KING       PRESIDENT       5000
MARTIN     SALESMAN        1250
WARD       SALESMAN        1250       1250
TURNER     SALESMAN        1500       1250
ALLEN      SALESMAN        1600       1500
14 rows selected.
SCOTT@yangdb>
使用分析函數的時候注意空值 或者null 給數據帶來的影響,數據是否允許爲空或者null 計算的時候會導致一定的差錯 比如 800-null 肯定爲null!這個結果是否是應用想要的結果?
細心很重要!!尤其是在計算和錢有關的情況下!!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章