lag()是一个分析函数,oracle 8i引入的,8i以后的版本都可用。
用此函数,你可以一次性从表中查询多条数据,而不需要将此表自连接。
它返回表中的当前行的前offset行的指定列值。
语法:
lag ( expression [, offset [, default] ] )
over ( [ query_partition_clause ] order_by_clause )
expression :可以包含oracle内置函数,但不能是任何分析函数。
offset :可选参数,是表中与当前行的物理偏移度,如果省略,默认值为1,
既当前行的前offset行。
default :可选参数,如果offset参数指向超出了表的范围,就返回这个值,默认值为null。
我们来看下面的实例:
原文:http://www.techonthenet.com/oracle/functions/lag.php
- SQL> select ename,sal from scott.emp
- 2 where sal>1500;
- ENAME SAL
- ---------- ---------
- ALLEN 1600.00
- JONES 2975.00
- BLAKE 2850.00
- CLARK 2450.00
- SCOTT 3000.00
- KING 5000.00
- FORD 3000.00
- --
- 1.下面使用默认值null
- SQL> select ename,job,sal,
- 2 lag(sum(sal),1) over (order by sal)
- 3 from scott.emp
- 4 where sal>1500
- 5 group by ename,job,sal;
- ENAME JOB SAL LAG(SUM(SAL),1)OVER(ORDERBYSAL
- ---------- --------- --------- ------------------------------
- ALLEN SALESMAN 1600.00
- CLARK MANAGER 2450.00 1600
- BLAKE MANAGER 2850.00 2450
- JONES MANAGER 2975.00 2850
- FORD ANALYST 3000.00 2975
- SCOTT ANALYST 3000.00 3000
- KING PRESIDENT 5000.00 3000
- --
- 2.首行用0替代null
- SQL> select ename,job,sal,
- 2 lag(sal,1,0) over (order by sal)
- 3 from scott.emp
- 4 where sal>1500;
- ENAME JOB SAL LAG(SAL,1,0)OVER(ORDERBYSAL)
- ---------- --------- --------- ----------------------------
- ALLEN SALESMAN 1600.00 0
- CLARK MANAGER 2450.00 1600
- BLAKE MANAGER 2850.00 2450
- JONES MANAGER 2975.00 2850
- SCOTT ANALYST 3000.00 2975
- FORD ANALYST 3000.00 3000
- KING PRESIDENT 5000.00 3000
- --
- 3.第一行显示其前面第三行(超出了表范围)数据(无用0替代)
- 所以下面的前三行都为0
- SQL> select ename,job,sal,
- 2 lag(sal,3,0) over (order by sal)
- 3 from scott.emp
- 4 where sal>1500;
- ENAME JOB SAL LAG(SAL,3,0)OVER(ORDERBYSAL)
- ---------- --------- --------- ----------------------------
- ALLEN SALESMAN 1600.00 0
- CLARK MANAGER 2450.00 0
- BLAKE MANAGER 2850.00 0
- JONES MANAGER 2975.00 1600
- SCOTT ANALYST 3000.00 2450
- FORD ANALYST 3000.00 2850
- KING PRESIDENT 5000.00 2975
- --
- 4.按job分组,下一而分组的第一个job显示上一个分组的第一个job的值,
- 所以下面你看到了4个0:
- 0-1:超出表范围,用0代替
- 0-2:第一个分组(SCOTT-ANALYST)的0值
- 0-3:第二个分组(CLARK-MANAGER )的0值
- 0-4:第三个分组(KING-PRESIDENT)的0值
- SQL> select ename,job,sal,
- 2 lag(sal,1,0) over (partition by job order by sal)
- 3 from scott.emp
- 4 where sal>1500;
- ENAME JOB SAL LAG(SAL,1,0)OVER(PARTITIONBYJO
- ---------- --------- --------- ------------------------------
- SCOTT ANALYST 3000.00 0
- FORD ANALYST 3000.00 3000
- CLARK MANAGER 2450.00 0
- BLAKE MANAGER 2850.00 2450
- JONES MANAGER 2975.00 2850
- KING PRESIDENT 5000.00 0
- ALLEN SALESMAN 1600.00 0
Oracle/PLSQL: Lag Function
In Oracle/PLSQL, the lag function is an analytic function that lets you query more than one row in a table at a time without having to join the table to itself. It returns values from a previous row in the table. To return a value from the next row, try using the lead function.
The syntax for the lag function is:
lag ( expression [, offset [, default] ] )
over ( [ query_partition_clause ] order_by_clause )
expression is an expression that can contain other built-in functions, but can not contain any analytic functions.
offset is optional. It is the physical offset from the current row in the table. If this parameter is omitted, the default is 1.
default is optional. It is the value that is returned if the offset goes out of the bounds of the table. If this parameter is omitted, the default is null.
Applies To:
- Oracle 8i, Oracle 9i, Oracle 10g, Oracle 11g
For example:
Let's take a look at an example. If we had an orders table that contained the following data:
ORDER_DATE PRODUCT_ID QTY 25/09/2007 1000 20 26/09/2007 2000 15 27/09/2007 1000 8 28/09/2007 2000 12 29/09/2007 2000 2 30/09/2007 1000 4
And we ran the following SQL statement:
select product_id, order_date,
lag (order_date,1) over (ORDER BY order_date) AS prev_order_date
from orders;
It would return the following result:
PRODUCT_ID ORDER_DATE PREV_ORDER_DATE 1000 25/09/2007 <NULL> 2000 26/09/2007 25/09/2007 1000 27/09/2007 26/09/2007 2000 28/09/2007 27/09/2007 2000 29/09/2007 28/09/2007 1000 30/09/2007 29/09/2007
Since we used an offset of 1, the query returns the previous order_date.
If we had used an offset of 2 instead, it would have returned the order_date from 2 orders before. If we had used an offset of 3, it would have returned the order_date from 3 orders before....and so on.
If we wanted only the orders for a given product_id, we could run the following SQL statement:
select product_id, order_date,
lag (order_date,1) over (ORDER BY order_date) AS prev_order_date
from orders
where product_id = 2000;
It would return the following result:
PRODUCT_ID ORDER_DATE PREV_ORDER_DATE 2000 26/09/2007 <NULL> 2000 28/09/2007 26/09/2007 2000 29/09/2007 28/09/2007
In this example, it returned the previous order_date for product_id = 2000 and ignored all other orders.
|