Lag函數可以在一次查詢中取出當前行的同一字段的前面第N行的數據。
Lead函數可以在一次查詢中取出當前行的同一字段的后面第N行的值。
這種操作可以使用對相同表的表連接來實現,不過使用LAG和LEAD有更高的效率。
over()表示 Lag()與Lead()操作的數據都在over()的范圍內,他里面可以使用partition by 語句(用於分組) order by 語句(用於排序)。
partition by a order by b表示以a字段進行分組,再 以b字段進行排序,對數據進行查詢。
例如:lead(field, num, defaultvalue) field需要查找的字段,num往后查找的num行的數據,defaultvalue沒有符合條件的默認值,num默認值為1。
leg(field, num, defaultvalue) field需要查找的字段,num往前查找的num行的數據,defaultvalue沒有符合條件的默認值,num默認值為1。
以下是lag例子:
沒有設置defaultvalue值.num默認是1:
select ename,job,sal ,lag(sal) over(order by sal) last_sal from emp;
ENAME JOB SAL LAST_SAL
---------- --------- ---------- ----------
SMITH CLERK 800 --此時沒有設置defaultvalue值 則為空值
JAMES CLERK 950 800 --這里的800來自第一行字段sal里的值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.
-------------------------------------------------------------------------------------------------------------------------
設置了defaultvalue值之后 第一行對應的值 為500:
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 --此時設置defaultvalue 值
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
-------------------------------------------------------------------------------------------------------------------------
指定num的值為2時
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 --這里的800來自第一行字段sal里的值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.
使用lead分析函數:
select ename,job,sal ,lead(sal) over(order by sal) last_sal from emp;
ENAME JOB SAL LAST_SAL
---------- --------- --------- ----------
SMITH CLERK 800 950 --這里的950來自第二行字段sal里的值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 --此時沒有設置defaultvalue值 則為空值
14 rows selected.
----------------------------------------------------------------------------------------------------------------------------
Lead和Lag函數也可以使用分組,以下是使用job 分組的例子:
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.
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.
注意:
使用分析函數的時候注意空值 或者null 給數據帶來的影響,數據是否允許為空或者null計算的時候會導致一定的差錯 比如 800-null 肯定為null!這個結果是否是應用想要的結果?