Oracle 中 rownumrow_number()rank()dense_rank() 函数的用法

Posted Abeam

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle 中 rownumrow_number()rank()dense_rank() 函数的用法相关的知识,希望对你有一定的参考价值。

Ø  简介

在之前还以为在 Oracle 中只能使用 rownum 这个伪列来实现分页,其实不然。在 Oracle 也与 MSSQL 一样,同样支持 row_number 函数,以及和 rankdense_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 表中46行的记录:

1)   首先,我们来看一个奇怪的现象

SELECT * FROM emp WHERE rownum >= 4 AND rownum <= 6;

啪,一执行,呀,怎么没数据啊?这并不是我们写错了,要解释这个问题,我们先来看一个图,就明白其中原由了。

clip_image002[1]

由图可以看出,当我们取出第一条记录时,此时(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;

clip_image004[1]

这样,通过子查询,先取出前6行,再过滤掉前3行,就得到了我们需要的数据。注意:之前提过,每个 SELECT 都会产生一个 rownum 序列号,所有上面会可以输出两个 rownum 序列号,dual 也不例外

SELECT t1.*, rownum FROM dual t1;

clip_image005[1]

 

3)   除了使用以上语句,我们还可以这样写

SELECT rownum, t1.* FROM (

  SELECT rownum rnum, t1.* FROM emp t1

) t1 WHERE t1.rnum >= 4 AND rnum <= 6; --或使用 BETWEEN 子句

clip_image007[1]

同样,可以完成以上功能。但分析一下,这种方式视乎没有上面的方式效率高,因为,这里是先查出所有(先将 rownum 分配好)数据,再进行第二次 rownum 过滤。

 

4)   有时候,我们还需要通过排序后再分页,该怎么实现呢?

使用排序并分页,也需要注意以下问题。

首先,我们来看下排序的全部数据:

SELECT * FROM emp ORDER BY sal;

clip_image009[1]

按照上面的要求,我们应该是取出 empno(7521,7654,7934) 的员工,OK

 

不是说用第一种方式,效率很高么?那就来使用它实现,更改的后的 SQL以上是关于Oracle 中 rownumrow_number()rank()dense_rank() 函数的用法的主要内容,如果未能解决你的问题,请参考以下文章

彻底删除Linux中oracle信息 实例

在PostgreSQL中使用oracle_fdw访问Oracle

oracle中DateDiff()的用法

oracle中DDL DML指啥?

oracle中INTERSECT,MINUS用法

oracle中DDL DML指啥?