一、RowNum

Rownum是oracle生成结果集时得到的一个伪列, 按照读出行的顺序, 第一条rownum=1, 第二条=2.

对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<、<=、!=),并非说用>,>=,=,between..and 时会提示SQL语法错误,而是经常是查不出一条记录来,还会出现似乎是莫名其妙的结果来,其实您只要理解好了这个 rownum 伪列的意义就不应该感到惊奇,同样是伪列,rownum 与 rowid 可有些不一样,下面以例子说明。

假设某个表 t1(c1) 有 20 条记录

如果用 select rownum,c1 from t1 where rownum < 10, 只要是用小于号,查出来的结果很容易地与一般理解在概念上能达成一致,应该不会有任何疑问的。

可如果用 select rownum,c1 from t1 where rownum > 10 (如果写下这样的查询语句,这时候在您的头脑中应该是想得到表中后面10条记录),你就会发现,显示出来的结果要让您失望了,也许您还会怀疑是不谁删了一些记录,然后查看记录数,仍然是 20 条啊?那问题是出在哪呢?

先好好理解 rownum 的意义吧。上面已经提到过, 因为ROWNUM是对结果集加的一个伪列,即先查到结果集之后再加上去的一个列 (强调:先要有结果集)。简单的说 rownum 是对符合条件结果的序列号。它总是从1开始排起的。所以你选出的结果不可能没有1,而有其他大于1的值。所以您没办法期望得到下面的结果集:

11 aaaaaaaa

12 bbbbbbb

13 ccccccc

.................

rownum >10 没有记录,因为第一条不满足去掉的话,第二条的ROWNUM又成了1,所以永远没有满足条件的记录。或者可以这样理解:

ROWNUM是一个序列,是oracle数据库从数据文件或缓冲区中读取数据的顺序。它取得第一条记录则rownum值为1,第二条为2,依次类推。如果你用>,>=,=,between...and这些条件,因为从缓冲区或数据文件中得到的第一条记录的rownum为1,则被删除,接着取下条,可是它的rownum还是1,又被删除,依次类推,便没有了数据。

有了以上从不同方面建立起来的对 rownum 的概念,那我们可以来认识使用 rownum 的几种现像

1. select rownum,c1 from t1 where rownum != 10 为何是返回前9条数据呢?它与 select 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 先生成,然后对他进行查询。

select *

from (selet rownum as rn,t1.* from a where ...)

where rn >10

一般代码中对结果集进行分页就是这么干的。

和rownum相似,oracle还提供了另外一个伪数列:rowid。不过rowid和rownum不同,一般说来每一行数据对应的rowid是固定而 且唯一的,在这一行数据存入数据库的时候就确定了。可以利用rowid来查询记录,而且通过rowid查询记录是查询速度最快的查询方法。(这个我没有试 过,另外要记住一个长度在18位,而且没有太明显规律的字符串是一个很困难的事情,所以我个人认为利用rowid查询记录的实用性不是很大)rowid只 有在表发生移动(比如表空间变化,数据导入/导出以后),才会发生变化。

rownum和排序

Oracle中的rownum的是在取数据的时候产生的序号,所以想对指定排序的数据去指定的rowmun行数据就必须注意了。

SQL> select rownum ,id,name from student order by name;

ROWNUM ID NAME

3 200003 李三

2 200002 王二

1 200001 张一

4 200004 赵四

可以看出,rownum并不是按照name列来生成的序号。系统是按照记录插入时的顺序给记录排的号,rowid也是顺序分配的。为了解决这个问题,必须使用子查询

SQL> select rownum ,id,name from (select * from student order by name);

ROWNUM ID NAME

1 200003 李三

2 200002 王二

3 200001 张一

4 200004 赵四

这样就成了按name排序,并且用rownum标出正确序号(有小到大)

笔者在工作中有一上百万条记录的表,在jsp页面中需对该表进行分页显示, 便考虑用rownum来作,下面是具体方法(每页显示20条):

“select * from tabname where rownum<20 order by name" 但却发现oracle却不能按自己的意愿来执行,而是先随便

取20条记录,然后再 order by,后经咨询oracle,说rownum确实就这样,想用的话,只能用子查询 来实现先排序,后rownum,方法如下:

"select * from (select * from tabname order by name) where rownum<20",但这样一来,效率会较低很多。

后经笔者试验,只需在order by 的字段上加主键或索引即可让oracle先按 该字段排序,然后再rownum;方法不变:

“select * from tabname where rownum<20 order by name"

二、RowId

rowid是物理结构上的,在每条记录insert到数据库中时,都会有一个唯一的物理记录 (不会变),
       例如  AAAMgzAAEAAAAAgAAB 7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30这里的AAAMgzAAEAAAAAgAAB物理位置对应了这条记录,这个记录是不会随着sql的改变而改变。

rowid和rownum都是虚列,但含义完全不同。rowid是物理地址,用于定位oracle中具体数据的物理存储位置,而rownum则是sql的输出结果排序。通俗的讲:rowid是相对不变的,rownum会变化,尤其是使用order by的时候。

rownum与rowId的更多相关文章

  1. Oracle中rownum和rowid的理解(转)

    本文转自地址http://www.linuxidc.com/Linux/2012-04/58300.htm rownum,rowid都叫伪列. 但是,rownum是逻辑上的编号,且其值总是从1开始,每 ...

  2. oracle中rownum和rowid的区别

    rownum和rowid的区别总括: rownum和rowid都是伪列,但是两者的根本是不同的. rownum是根据sql查询出的结果给每行分配一个逻辑编号,所以你的sql不同也就会导致最终rownu ...

  3. Oracle中rownum和rowid的理解

    rownum,rowid都叫伪列. 但是,rownum是逻辑上的编号,且其值总是从1开始,每行的rounum不是固定的.而rowid是“物理”编号.若数据库文件没有移动,则每行的 rowid一般是固定 ...

  4. oracle中rownum和rowid的区别【转】

    rownum和rowid的区别总括: rownum和rowid都是伪列,但是两者的根本是不同的. rownum是根据sql查询出的结果给每行分配一个逻辑编号,所以你的sql不同也就会导致最终rownu ...

  5. 伪列ROWNUM、ROWID部分用法

    ROWNUM是逻辑值,不可以参与计算 ROWID是物理值,可以参与计算 在ROWNUM和ROWID使用中,现将查找结果形成一个结果集 在结果集中给ROWID 和ROWNUM别名,在外层中使用这个别名找 ...

  6. oracle数据库之rownum和rowid用法

    Rownum 和 Rowid是Oracle数据库所特有的,通过他们可以查询到指定行数范围内的数据记录.   以下通过例子讲解: -- 为了方便,首先,查找dept表中的所有. select deptn ...

  7. Oracle Schema Objects——伪列ROWID Pseudocolumn(ROWNUM、ROWID)

    Oracle Schema Objects Oracle Schema Objects——Tables——Oracle Data Types Oracle伪列 在Oracle数据库之中为了实现完整的关 ...

  8. Oracle中的rownum 和rowid的用法和区别

    Oracle中的rownum 和rowid的用法和区别   1.rownum是伪列,是在获取查询结果集后再加上去的 (获取一条记录加一个rownum).对符合条件的结果添加一个从1开始的序列号. eg ...

  9. rownum和rowid伪列

    select row employee_id,last name,salary from employees; select row employee_id,last name,salary from ...

随机推荐

  1. delphi获取mdb密码

    function GetPasswordFromAccess(AFileName: string): string;var  myms: TMemoryStream;  b: array of Byt ...

  2. IOS学习笔记1`

    写了IOS的Hello World,记事本写的.除了一些基本的语法外,最主要的收获就是路径问题了. 直接把文件拖入终端,就会显示文件的完全限定名了.

  3. Deep learning:三十四(用NN实现数据的降维)

    数据降维的重要性就不必说了,而用NN(神经网络)来对数据进行大量的降维是从2006开始的,这起源于2006年science上的一篇文章:reducing the dimensionality of d ...

  4. 50道经典的JAVA编程题(36-40)

    50道经典的JAVA编程题(36-40),今天晚上心情压抑,不爽,继续做题,管它明天考试,我继续我的java,一个周末都在看微机原理看得的很头疼啊~明天该挂科就挂吧,不在乎了~~~ [程序36] Ar ...

  5. python打包成exe(py2exe)

    对比了几个打包工具,发现py2exe更好用一点,一个命令就可以. 1.获取 http://prdownloads.sourceforge.net/py2exe 下载python版本对应的.直接下载然后 ...

  6. 【转载】C/C++语言void及void指针深层探索

    C/C++语言void及void指针深层探索 1.概述许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误.本文将对void关键字的深刻含义进行解说,并详述vo ...

  7. MapReduce之Partition的使用与分析

    Partition主要作用就是将map的结果发送到相应的reduce.这就对partition有两个要求: 1)均衡负载,尽量的将工作均匀的分配给不同的reduce. 2)效率,分配速度一定要快. M ...

  8. Hadoop概念学习系列之谈谈RPC(三十三)

    RPC-------->远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数 ...

  9. Java网络编程(TCP客户端)

    TCP传输:两个端点建立连接后会有一个传输数据的通道,这个通道就称为流,而且是建立在网络基础上的流,之为socket流,该流中既可以读取也可以写入. TCP的两个端点:一个客户端:ServerSock ...

  10. Android实例-MediaPlayer播放音乐和视频(XE8+小米2)

    结果: 1.播放视频需要手动放入MediaPlayerControl1控件,设置MediaPlayerControl1.MediaPlayer := MediaPlayer1; 2.播放声音文件正常, ...