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用法总结!
对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号 返回的第一行分配的是 第二行是 依此类推 这个伪字段可以用于限制查询返回的总行数 而且rownum不能以任何表的名称作为前缀
举例说明
例如表 student(学生)表 表结构为
ID varchar ( ) 学号
namevarchar ( ) 姓名
create table student (ID varchar ( ) name varchar ( ))
insert into student values( 张一 )
insert into student values( 王二 )
insert into student values( 李三 )
insert into student values( 赵四 )
mit
( ) rownum 对于等于某值的查询条件
如 果希望找到学生表中第一条学生的信息 可以使用rownum= 作为条件 但是想找到学生表中第二条学生的信息 使用rownum= 结果查不到数据 因 为rownum都是从 开始 但是 以上的自然数在rownum做等于判断是时认为都是false条件 所以无法查到rownum = n(n>的自然数)
SQL>select rownum id name from student where rownum= (可以用在限制返回记录条数的地方 保证不出错 如 隐式游标)
SQL>select rownum id name from student where rownum=
ROWNUM ID NAME
张一
SQL>select rownum id name from student where rownum =
ROWNUM ID NAME
( )rownum对于大于某值的查询条件
如果想找到从第二行记录以后的记录 当使用rownum>是查不出记录的 原因是由于rownum是一个总是从 开始的伪列 Oracle 认为rownum>n(n>的自然数)这种条件依旧不成立 所以查不到记录
SQL>select rownum id name from student where rownum >
ROWNUM ID NAME
那如何才能找到第二行以后的记录呀 可以使用以下的子查询方法来解决 注意子查询中的rownum必须要有别名 否则还是不会查出记录来 这是因为rownum不是某个表的列 如果不起别名的话 无法知道rownum是子查询的列还是主查询的列
SQL>select * from(select rownum no id name from student) where no>
NO ID NAME
李三
赵四
SQL>select * from(select rownum id name from student)where rownum>
ROWNUM ID NAME
( )rownum对于小于某值的查询条件
如果想找到第三条记录以前的记录 当使用rownum<是能得到两条记录的 显然rownum对于rownum<n((n>的自然数)的条件认为是成立的 所以可以找到记录
SQL>select rownum id name from student where rownum <
ROWNUM ID NAME
张一
王二
综 上几种情况 可能有时候需要查询rownum在某区间的数据 那怎么办呀从上可以看出rownum对小于某值的查询条件是人为true的 rownum对 于大于某值的查询条件直接认为是false的 但是可以间接的让它转为认为是true的 那就必须使用子查询 例如要查询rownum在第二行到第三行之 间的数据 包括第二行和第三行数据 那么我们只能写以下语句 先让它返回小于等于三的记录行 然后在主查询中判断新的rownum的别名列大于等于二的记 录行 但是这样的 *** 作会在大数据集中影响速度
SQL>select * from (select rownum no id name from student where rownum<= ) where no >=
NO ID NAME
王二
李三
( )rownum和排序
Oracle中的rownum的是在取数据的时候产生的序号 所以想对指定排序的数据去指定的rowmun行数据就必须注意了
SQL>select rownum id name from student order by name
ROWNUM ID NAME
李三
王二
张一
赵四
可以看出 rownum并不是按照name列来生成的序号 系统是按照记录插入时的顺序给记录排的号 rowid也是顺序分配的 为了解决这个问题 必须使用子查询
SQL>select rownum id name from (select * from student order by name)
ROWNUM ID NAME
李三
王二
张一
赵四
这样就成了按name排序 并且用rownum标出正确序号(有小到大)
笔者在工作中有一上百万条记录的表 在jsp页面中需对该表进行分页显示 便考虑用rownum来作 下面是具体方法(每页
显示 条)
select * from tabname where rownum<order by name 但却发现oracle却不能按自己的意愿来执行 而是先随便取 条记录 然后再 order by 后经咨询oracle 说rownum确实就这样 想用的话 只能用子查询 来实现先排序 后rownum 方法如下
select * from (select * from tabname order by name) where rownum<但这样一来 效率会较低很多
后经笔者试验 只需在order by 的字段上加主键或索引即可让oracle先按 该字段排序 然后再rownum 方法不变
select * from tabname where rownum<order by name
取得某列中第N大的行
select column_name from
(select table_name * dense_rank() over (order by column desc) rank from table_name)
where rank = &N
假如要返回前 条记录
select * from tablename where rownum<(或是rownum <= 或是rownum != )
假如要返回第 条记录
select * from tablename
where …
and rownum<
minus
select * from tablename
where …
and rownum<
order by name
选出结果后用name排序显示结果 (先选再排序)
注意 只能用以上符号(<<= !=)
select * from tablename where rownum != 返回的是前9条记录
不能用 >>= = Beeen and 由于rownum是一个总是从 开始的伪列 Oracle 认为这种条件 不成立 查不到记录
另外 这个方法更快
select * from (
select rownum r a from yourtable
where rownum <=
order by name )
where r >
这样取出第 条记录!(先选再排序再选)
要先排序再选则须用select嵌套 内层排序外层选 rownum是随着结果集生成的 一旦生成 就不会变化了 同时 生成的结果是依次递加的 没有 就永远不会有 rownum 是在 查询集合产生的过程中产生的伪列 并且如果where条件中存在 rownum 条件的话 则:
假如 判定条件是常量 则
只能 rownum = <= 大于 的自然数 = 大于 的数是没有结果的 大于一个数也是没有结果的
即 当出现一个 rownum 不满足条件的时候则 查询结束 this is stop key!
: 当判定值不是常量的时候
lishixinzhi/Article/program/Oracle/201311/17923
一、rownum的说明
rownum是oracle特有的一个关键字。
(1)对于基表,在insert记录时,oracle就按照insert的顺序,将rownum分配给每一行记录,因此在select一个基表的时候,rownum的排序是根据insert记录的顺序显示的,例如:
(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并不是当作实体数据存放在每一张表中,而是在每一次select查询的时候,根据基表的默认insert顺序由oracle动态分配的,有1才有2,如果rownum没有1,那么2也就没有了意义,所以这个查询就不会有任何结果出来。这个时候我们就需要利用子查询和别名列来实现这个需求:
首先通过子查询,取出emp表的前2条记录,并将子查询中的rownum定义为别名rn,然后在外层查询中,使用where条件使rn=2即可,查询出emp表的第二条记录:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)