在oracle中ROWNUM是什么东西?拜托各位大神
ROWNUM是一个序列,是oracle数据库从数据文件或缓冲区中读取数据的顺序。它取得第一条记录则rownum值为1,第二条为2,依次类推。如果你用>,>=,=,between...and这些条件,因为从缓冲区或数据文件中得到的第一条记录的rownum为1,则被删除,接着取下条,可是它的rownum还是1,又被删除,依次类推,便没有了数据。 有了以上从不同方面建立起来的对 rownum 的概念,那我们可以来认识使用 rownum 的几种现像 1. lect rownum,c1 from t1 where rownum != 10 为何是返回前9条数据呢?它与 lect rownum,c1 from tablename where rownum < 10 返回的结果集是一样的呢? 因为是在查询到结果集后,显示完第 9 条记录后,之后的记录也都是 != 10,或者 >=10,所以只显示前面9条记录。也可以这样理解,rownum 为9后的记录的 rownum为10,因条件为 !=10,所以去掉,其后记录补上,rownum又是10,也去掉,如果下去也就只会显示前面9条记录了 2. 为什么 rownum >1 时查不到一条记录,而 rownum >0 或 rownum >=1 却总显示所以的记录 因为rownum 是在查询到的结果集后加上去的,它总是从1开始 3. 为什么 between 1 and 10 或者 between 0 and 10 能查到结果,而用 between 2 and 10 却得不到结果 原因同上一样,因为 rownum 总是从 1 开始 从上可以看出,任何时候想把 rownum = 1 这条记录抛弃是不对的,它在结果集中是不可或缺的,少了rownum=1 就像空中楼阁一般不能存在,所以你的 rownum 条件要包含到 1 但如果就是想要用 rownum > 10 这种条件的话话就要用嵌套语句,把 rownum 先生成,然后对他进行查询。 lect * from (let rownum as rn,t1.* from a where ...) where rn >10 一般代码中对结果集进行分页就是这么干的。 另外:rowid 与 rownum 虽都被称为伪列,但它们的存在方式是不一样的,rowid 可以说是物理存在的,表示记录在表空间中的唯一位置ID,在DB中唯一。只要记录没被搬动过,rowid是不变的。rowid 相对于表来说又像表中的一般列,所以以 rowid 为条件就不会有 rownum那些情况发生。 另外还要注意:rownum不能以任何基表的名称作为前缀。 oracle的rownum是在提取记录就已经生成,它先于排序操作,所以必须使用子查询先排序 。 ROWNUM值的分配是在查询的谓词解析之后,任何排序和聚合之前进行的。
Oracle 分页查询rownum的用法
对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,且rownum不能以任何表的名称作为前缀。
(1) rownum 对于等于某值的查询条件
如果希望找到学生表中第一条学生的信息,可以使用rownum=1作为条件。但是想找到学生表中第二条学生的信息,使用rownum=2结果查不到数据。因为rownum都是从1开始,但是1以上的自然数在rownum做等于判断是时认为都是fal条件,所以无法查到rownum = n(n>1的自然数)。
SQL> lect rownum,id,name from student where rownum=1;(可以用在限制返回记录条数的地方,保证不出错,如:隐式游标)
SQL> lect rownum,id,name from student where rownum =2;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
(2)rownum对于大于某值的查询条件
如果想找到从第二行记录以后的记录,当使用rownum>2是查不出记录的,原因是由于rownum是一个总是从1开始的伪列,Oracle 认为rownum> n(n>1的自然数)这种条件依旧不成立,所以查不到记录。
查找到第二行以后的记录可使用以下的子查询方法来解决。注意子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。
SQL>lect * from(lect rownum no ,id,name from student) where no>2;
NO ID NAME
---------- ------ ---------------------------------------------------
3 200003 李三
4 200004 赵四
(3)rownum对于小于某值的查询条件
rownum对于rownum 1的自然数)的条件认为是成立的,所以可以找到记录。
SQL> lect rownum,id,name from student where rownum lect * from (lect rownum no,id,name from student where rownum=2;
NO ID NAME
---------- ------ ---------------------------------------------------
2 200002 王二
3 200003 李三
(4)rownum和排序
Oracle中的rownum的是在取数据的时候产生的序号,所以想对指定排序的数据去指定的rowmun行数据就必须注意了。
SQL> lect rownum ,id,name from student order by name;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
3 200003 李三
2 200002 王二
1 200001 张一
4 200004 赵四
可以看出,rownum并不是按照name列来生成的序号。系统是按照记录插入时的顺序给记录排的号,rowid也是顺序分配的。为了解决这个问题,必须使用子查询;
SQL> lect rownum ,id,name from (lect * from student order by name);
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
1 200003 李三
2 200002 王二
3 200001 张一
4 200004 赵四
这样就成了按name排序,并且用rownum标出正确序号(有小到大)
rownum的理解
楼主您好
rownum是一个伪列,始终是从1开始的
所以我们比如要差第10行以后的数据,不能直接rownum>10
而必须把rownum字段取个别名作为一个子查询,然后用这个新增的字段再>10这样就是所谓的“固化”
Oracle之rownum(转载)
一、rownum的说明
rownum是oracle特有的一个关键字。
(1)对于基表,在inrt记录时,oracle就按照inrt的顺序,将rownum分配给每一行记录,因此在lect一个基表的时候,rownum的排序是根据inrt记录的顺序显示的,例如:
(2)对于子查询,则rownum的顺序是根据子查询的查询顺序进行动态分配的,例如:
由上图可以看到T1_RN和T2_RN的区别。
t1中的rownum是根据emp这个基表的默认顺序分配的,而内层子循环是根据SAL字段进行排序,所以t2的rownum是根据内层子查询的记录顺序分配的。
----------------------------- 分 割 线 -------------------------------------
二、rownum的一些使用技巧
(1)使用rownum限制查询返回的记录数
1、例如,我们现在只想看到emp表中的第一条记录:
将rownum限制为1,这样就只能查询出一条记录。
2、现在,我们现在想查看emp中的前2条记录:
将rownum的限制为2条,这样就可以查询出前2条记录。
3、假如我们现在只想查看emp中的第二条记录,又该如何写语句呢?
如果我们先这样写:
where条件为:rownum=2,来看看查询结果:
发现没有查出任何数据,为什么呢?这里就要对oracle的rownum做进一步的理解。
因为rownum并不是当作实体数据存放在每一张表中,而是在每一次lect查询的时候,根据基表的默认inrt顺序由oracle动态分配的,有1才有2,如果rownum没有1,那么2也就没有了意义,所以这个查询就不会有任何结果出来。这个时候我们就需要利用子查询和别名列来实现这个需求:
首先通过子查询,取出emp表的前2条记录,并将子查询中的rownum定义为别名rn,然后在外层查询中,使用where条件使rn=2即可,查询出emp表的第二条记录:
Oracle数据库rownum和row_number的不同点
明确对于rownum
来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是二,以此类推,这个为字段可以用于限制查询的返回的总行数,因为rownum总是从1开始,但是1以上的自然数在rownum
做等于判断时都认为是fal
条件,所以无法查到
rownum=n
(n》1的自然数),所以查找第二行以后的记录可以用子查询方法来解决,给子查询中的rownum取别名;对于小于某个值的情况两种方法都差不多,但是对于某个不等于一的值或者求某个值到某个值之间的情况,用row_number()
别名获得排名
,比用rownum伪列要简单方便的多;因为伪列总是从一开始查找;
具体用法和区别参见以下代码;
--取出工资最高的前5位
lect
empno,ename,sal,rownum
from
emp;
lect
*
from
(lect
*
from
emp
order
by
sal
desc)
where
rownum<=5;
lect
*
from
(lect
ename,sal,row_number()
over(order
by
sal
desc)
as
num
from
emp)
where
num<=5;
lect
*
from
(lect
ename,sal,row_number()
over(order
by
sal
desc)
from
emp)
where
rownum<=5
--工资的前3名
lect
*
from
emp
where
sal
>=any(lect
*
from
(lect
sal
from
emp
order
by
sal
desc)
where
rownum<=3);
lect
*
from(lect
*
from
emp
order
by
sal
desc)
where
rownum
<4;
lect
*
from
(lect
ename,sal,empno,deptno
,row_number()
over
(order
by
sal
desc)
from
emp)
where
rownum<4;
lect
*
from
(lect
ename,sal,empno,deptno
,row_number()
over
(order
by
sal
desc)
as
num
from
emp)
where
num<4
--按照工资排序,取出第6名到第10名
--使用伪列获得
lect
*
from
(lect
ename,sal,rownum
r
from
(lect
*
from
emp
order
by
sal
desc)
where
rownum<=10)
where
r>5;
--使用排名函数获得
lect
*
from
(lect
ename,sal,row_number()
over(order
by
sal
desc)
as
num
from
emp)
where
num>5
and
num<=10;
-------
按工资从高到低获得工资排名第四的员工
lect
*
from
(lect
ename,sal,row_number()
over(order
by
sal
desc)
as
num
from
emp)
where
num=4;
lect
*
from
(lect
ename,sal,rownum
r
from
(lect
*
from
emp
order
by
sal
desc)
where
rownum<=4)
where
r=4;
总结oracle中rownum和row_number()的区别
row_number()是分析函数,基本语法为row_number()
over(partition
by
字段
order
by
字段)
rownum是一个伪列
lect
*
from
dept
where
rownum<=3;
lect
*
from
dept
where
rownum
between
2
and
3;这儿会出错,因为rownum的特性(没有1就不会有2,没有3)决定的
SELECT
*
FROM
(SELECT
A.*,ROWNUN
FROM
DEPT
A)T1
WHERE
T1.ROWNUM
BETWEEN
2
AND
3;这么写不对,要这样写
SELECT
*
FROM
(SELECT
A.*,ROWNUM
RN
FROM
DEPT
A)T1
WHERE
T1.RN
BETWEEN
2
AND
3;
他们的主要区别是:使用rownum进行排序的时候是先对结果集加入伪列rownum然后再进行排序,而函数row_number()在包含排序从句后是先排序再计算行号码。
oracle中ROWNUM使用
Q提出想要把tableA表按照col2列排序后,找出第5-10行记录。咋搞?
按照特定条件查找出前N行数据,可以通过 ROWNUM 解决。
ROWNUM 又被称为 伪列 ,伪列就像在在表中有这么一列,但并不存储在表中,能够基于伪列进行从查询,也能够基于 ROWNUM 进行更新删除操作,例如
不过由于ROWNUM会随着条件限制、表记录更改等发生变化,并不是表记录的真实值,所以尽量避免用ROWNUM来进行删改操作。
ROWNUM 支持能够查出正确记录的操作符为<code><</code>、<code><=</code>、<code>!=</code>、<code>=1</code>,对于<code>></code>、<code>>=</code>、<code>=N(N>1)</code>、<code>BETWEEN…AND…</code>运行时不报错,但直接使用不能查询出正确结果。
ROWNUM 是在查询出结果集后,给结果集添加上一个伪列,类似于给查询出的结果标上序号,序号从1开始,连续递增,不存在序号跳跃的现象。例如:
结果为:
如果加上限制条件:
结果为:
原来第4行会变成第3行,所以如果用<code>WHERE ROWNUM > 3</code>来进行查询时,并不会有任何结果,因为第一条记录(ROWNUM=1)不满足条件被去掉后,原第二条记录就成为第一条记录(ROWNUM=1),仍旧不满足被去掉,以此类推,所以永远不会有大于3的记录。由此,使用<code>ROWNUM != 2</code>与<code>ROWNUM < 2</code>等价。
回到刚开始的问题,既然ROWNUM不支持BETWEEN…AND…,>号这些,那如何得到第5-10行记录呢?
可以通过使用子集查询来解决:
使用了两次子集查询,第一次是按照col2进行排序,确保使用ROWNUM得到的是有序的结果集,第二次是用ROWNUM找出前10行记录,并将ROWNUM起别名RID保存到临时表,最后通过RID来限制第5行以后记录。这样就得到了第5-10有序记录。
对于为何先使用ORDER BY 再使用ROWNUM<=10的解释:
对于刚开始的问题,还可以使用以下子集查询进行解决:
使用MINUS
使用INTERSECT
ORACLE中的rownum
ORACLE 中ROWNUM用法总结!