Oracle FIRST_VALUE和LAST_VALUE函数
first_value和last_value都属于分析函数。根据Oracle官方文档的描述first_value返回一个排序数据集合的第一行,last_value返回一个排序数据集合的最后一行。根据描述它们好像是一对相反的函数,一个返回第一行,一个返回最后一行,事实真是这样吗?
拿scot.emp表的数据举例说明:
1* select deptno,sal from emp where deptno=10 21:45:18 SCOTT@ orcl>/ DEPTNO SAL ---------- ---------- 10 2450 10 5000 10 1300
部门编号10有三个人他们的工资分别是2400,5000,1300
现在将工资按从少到多排序,使用first_value返回第一行数据,应该是1300
22:19:34 SCOTT@ orcl>select distinct deptno,first_value(sal) over(order by sal) first_sal,sal from emp where deptno=10 22:21:02 2 / DEPTNO FIRST_SAL SAL ---------- ---------- ---------- 10 1300 2450 10 1300 5000 10 1300 1300
同样将工资从少到多排序,使用last_value返回最后一行,应该是5000
1* select distinct deptno,last_value(sal) over(order by sal) last_sal,sal from emp where deptno=10 22:04:09 SCOTT@ orcl>/ DEPTNO LAST_SAL SAL ---------- ---------- ---------- 10 2450 2450 10 5000 5000 10 1300 1300
为什么和预想的不一样,原来Oracle的分析函数都有一个窗口子句,两次查询都没有指定窗口子句,所以函数使用了默认的窗口子句:RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW。即窗口的上界是无界,下界是当前行。
对于1300它的上界是1300下界也是1300所以最后一行是1300
对于2450它的上界是1300下界是2450所以最后一行是2450
对于5000它的上界是1300下界是5000所以最后一行是5000
同样的分析方法也适用于first_value
如果想返回某一组的最后一个值,需要显示声明窗口子句,让窗口的上界无界,下界也是无界这样,该组的数据将共享一个窗口数据。(对于上面的例子就是上界1300下界5000)
22:19:29 SCOTT@ orcl>SELECT DISTINCT deptno 22:19:31 2 ,last_value(sal) over(ORDER BY sal rows BETWEEN unbounded preceding AND unbounded following) last_sal 22:19:31 3 ,sal 22:19:31 4 FROM emp 22:19:31 5 WHERE deptno = 10 22:19:33 6 / DEPTNO LAST_SAL SAL ---------- ---------- ---------- 10 5000 1300 10 5000 5000 10 5000 2450