Oracle 中 rownumrow_number()rank()dense_rank() 函数的用法
Posted Abeam
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle 中 rownumrow_number()rank()dense_rank() 函数的用法相关的知识,希望对你有一定的参考价值。
Ø 简介
在之前还以为在 Oracle 中只能使用 rownum 这个伪列来实现分页,其实不然。在 Oracle 也与 MSSQL 一样,同样支持 row_number 函数,以及和 rank、dense_rank 这两个函数。下面就来讨论 rownum 与 row_number 函数的区别,以及另外两个函数的使用。
1. rownum 的使用
2. rownum 使用需谨慎
3. row_number() 函数
4. rank() 与 dense_rank() 函数
5. over() 函数结合聚合函数的使用
6. 综合案例
1. rownum 的使用
rownum 是 Oracle 在查询时对结果集输出的一个伪列,这个列并不是真实存在的,当我们进行每一个 SELECT 查询时,Oracle 会帮我们自动生成这个序列号(rownum),该序列号是顺序递增的,用于标识行号。通常可以借助 rownum 来实现分页,下面来看具体实现,比如我们需要取 emp 表中4到6行的记录:
1) 首先,我们来看一个奇怪的现象
SELECT * FROM emp WHERE rownum >= 4 AND rownum <= 6;
啪,一执行,呀,怎么没数据啊?这并不是我们写错了,要解释这个问题,我们先来看一个图,就明白其中原由了。
由图可以看出,当我们取出第一条记录时,此时(rownum = 1) >= 3不成立,所以该记录会被排除;然后再取第二条,此时任然 rownum = 1,因为只有成功满足一条记录,rownum 才会加1,所以不满足又被排除掉了。这样依次类推,最终都不满足条件,所以全部都被排除掉了。所以,以下语句始终查不出数据:
SELECT * FROM emp WHERE rownum > 1;
然后,在看另外一边(就是接下来用的这种判断方式),首先取第一条(满足),第二条也满足,直到(rownum = 7) <= 6,所以会取出6条记录,此时 rownum 的值为1,2,3,4,5,6。好了,搞清楚原理后我们就来实现。
2) 根据对 rownum 的分析,便改为以下语句
SELECT rownum, t1.* FROM (
SELECT rownum rnum, t1.* FROM emp t1 WHERE rownum <= 6
) t1 WHERE t1.rnum >= 4;
这样,通过子查询,先取出前6行,再过滤掉前3行,就得到了我们需要的数据。注意:之前提过,每个 SELECT 都会产生一个 rownum 序列号,所有上面会可以输出两个 rownum 序列号,dual 也不例外:
SELECT t1.*, rownum FROM dual t1;
3) 除了使用以上语句,我们还可以这样写
SELECT rownum, t1.* FROM (
SELECT rownum rnum, t1.* FROM emp t1
) t1 WHERE t1.rnum >= 4 AND rnum <= 6; --或使用 BETWEEN 子句
同样,可以完成以上功能。但分析一下,这种方式视乎没有上面的方式效率高,因为,这里是先查出所有(先将 rownum 分配好)数据,再进行第二次 rownum 过滤。
4) 有时候,我们还需要通过排序后再分页,该怎么实现呢?
使用排序并分页,也需要注意以下问题。
首先,我们来看下排序的全部数据:
SELECT * FROM emp ORDER BY sal;
按照上面的要求,我们应该是取出 empno(7521,7654,7934) 的员工,OK。
不是说用第一种方式,效率很高么?那就来使用它实现,更改的后的 SQL:以上是关于Oracle 中 rownumrow_number()rank()dense_rank() 函数的用法的主要内容,如果未能解决你的问题,请参考以下文章