知识点内容ROWNUM是一个伪列,用于标识从一个表或一组连接(JOIN)表中查询数据时返回记录的顺序。Oracle在执行select查询时,会按照返回行的顺序为行分配一个序号:第一个返回行的序号为1,第二个行的序号为2,依此类推。这个序号就是每一行的rownum。ORACLE中ROWNUM使用总结对于Oracle的rownum问题,很多资料说不支持>,>=,=,between...and,只能用上面的符号(<,<=,!=),not>,>=,=,between..and会提示SQL语法错误,但往往找不到一条记录,还会出现看似莫名其妙的结果,其实只要理解rownum伪的含义就可以了专栏这应该不足为奇。它也是一个伪列。rownum和rowid有点不同。下面的例子说明:假设表t1(c1)有20条记录。如果使用selectrownum,c1fromt1whererownum<10,只要使用小于号,结果很容易在概念上与一般理解一致,所以应该没有疑问。但是如果你使用selectrownum,c1fromt1whererownum>10(如果你写这样的查询语句,此时你应该是想获取表中的最后10条记录),你会发现显示的结果应该是让你下来,也许你还在疑惑是不是有人删除了一些记录,然后查看记录的数量,还有20条记录?哪里有问题?先了解一下rownum的含义。因为ROWNUM是添加到结果集中的伪列,即先找到结果集后添加的列(强调:先要有结果集)。简单的说,rownum就是符合条件的结果的序号。它总是从1开始。所以你选择的结果不可能没有1,而是有其他大于1的值。所以你不能指望得到如下结果集:11aaaaaaaa12bbbbbbb13cccccccc...........rownum>10就没有记录了,因为如果第一项不满足,你去掉它,第二个ROWNUM又变成了1,所以永远不会有满足条件的记录。或者你可以这样理解:ROWNUM是一个序列,就是oracle数据库从数据文件或缓冲区中读取数据的顺序。它得到第一条记录,rownum值为1,第二条为2,依此类推。如果使用>,>=,=,between...等这些条件,因为从buffer或者数据文件中获取的第一条记录的rownum为1,所以会被删除,然后bar会被去掉,但是它的rownum还是1,删除了,以此类推,没有数据了。有了上面从不同方面建立的rownum的概念,我们可以理解使用rownum的几种现象:1.selectrownum,c1fromt1whererownum!=10为什么返回的是前9条数据?和selectrownum,c1fromt1whererownum<10返回的结果集一样吗?因为查询结果集,显示第9条记录后,后面的所有记录都是!=10,或者>=10,所以只显示前9条记录。也可以这样理解,rownum为9之后的记录的rownum为10,因为条件是!=10,所以去掉,后面的记录追加,rownum为10,就可以了也被删除。如果出现故障,则只会显示前9条记录。2、为什么rownum>1时找不到记录,而rownum>0或rownum>=1时却一直显示所有记录,因为rownum是在查询结果集后面加上的,总是从1开始的。3.为什么使用1到10之间或者0到10之间可以找到结果,但是2到10之间不能找到结果,原因和上面一样,因为rownum总是从1开始,从上面可以看出,任意当你想丢弃rownum=1记录时是错误的。在结果集中是不可或缺的。如果没有rownum=1,就像空中楼阁,无法存在,所以你的rownum条件必须包含1。但是如果你只是想使用rownum>10的条件,你需要先使用嵌套语句生成rownum,然后查询它。select*from(seletrownumasrn,t1.*fromawhere...)whereern>10一般代码中结果集是这样分页的。另外:rowid和rownum虽然都叫伪列,但是它们的存在方式不同。rowid可以说是物理存在的,表示表空间中记录的最大位置ID,在DB中的最大值。只要记录没有被移动,rowid就不会改变。相对于表,rowid就像是表中的一个通用列,所以如果以rowid作为条件,就没有rownum了。另请注意:rownum不能以任何基表的名称为前缀。2.实验过程为了更清楚地展示ROWNUM的用法,这里做了一些简单的实验。例如表:student(学生)表,表结构为:ID char(10)--学号name VARCHAR2(20) --namecreatetablestudent(IDchar(6),nameVARCHAR2(20));insertintostudentvalues('200001','张毅');insertintostudentvalues('200002','王二');insertintostudentvalues('200003','李三');insertintostudentvalues('200004','赵Si');犯罪;1、对于等于某个值的查询条件,如果要查找student表中第一个学生的信息,可以使用rownum=1作为条件。但是如果我想在student表中查找第二个学生的信息,使用rownum=2是找不到数据的。因为rownum是从1开始的,但是在rownum等于判断的时候认为1以上的自然数为假条件,所以rownum=n(n>1的自然数)是找不到的。SQL>selectrownum,id,namefromstudentwhererownum=1;(可以用来限制返回记录的条数,保证不报错,如:隐式游标)SQL>selectrownum,id,namefromstudentwhererownum=1;ROWNUMIDNAME----------------------------------------------1200001张SQL>selectrownum,id,namefromstudentwhererownum=2;ROWNUMIDNAME-------------------------------------------------2。如果rownum大于某个值,如果要查找第二行之后的记录,当rownum>2时,是找不到记录的。原因是rownum总是从1开始的伪列,Oracle认为rownum>n(n>1的自然数)的条件还是不成立,所以查不到记录SQL>selectrownum,id,namefromstudentwhererownum>2;ROWNUMIDNAME第二行之后的记录呢?可以使用下面的子查询方法来解决。注意子查询中的rownum必须有别名,否则找不到记录。这是因为rownum不是某个表的列。如果没有别名,就无法知道rownum是子查询的列还是主查询的列。.SQL>select*from(selectrownumno,id,namefromstudent)whereno>2;NOIDNAME3200003李三4200004赵四SQL>select*from(selectrownum,id,namefromstudent)whererownum>2;ROWNUMIDNAME3.rownum查找第三条记录之前的记录。当使用rownum<3时,可以得到两条记录。显然rownum认为rownum
