`
jarit
  • 浏览: 139636 次
社区版块
存档分类
最新评论

oracle rownum与order by

阅读更多

对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,而且rownum不能以任何表的名称作为前缀。
举例说明:
例如表:student(学生)表,表结构为:
ID        char(6)      --学号
name    VARCHAR2(10)   --姓名
create table student (ID char(6), name VARCHAR2(100));
insert into sale values('200001',‘张一’);
insert into sale values('200002',‘王二’);
insert into sale values('200003',‘李三’);
insert into sale values('200004',‘赵四’);
commit;

(1) rownum 对于等于某值的查询条件
如果希望找到学生表中第一条学生的信息,可以使用rownum=1作为条件。但是想找到学生表中第二条学生的信息,使用rownum=2结果查不到数据。因为rownum都是从1开始,但是1以上的自然数在rownum做等于判断是时认为都是false条件,所以无法查到rownum = n(n>1的自然数)。
SQL> select rownum,id,name from student where rownum=1;(可以用在限制返回记录条数的地方,保证不出错,如:隐式游标)
SQL> select rownum,id,name from student where rownum=1;
     ROWNUM ID      NAME
---------- ------ ---------------------------------------------------
          1 200001 张一
SQL> select rownum,id,name from student where rownum =2;
     ROWNUM ID      NAME
---------- ------ ---------------------------------------------------

(2)rownum对于大于某值的查询条件
    如果想找到从第二行记录以后的记录,当使用rownum>2是查不出记录的,原因是由于rownum是一个总是从1开始的伪列,Oracle 认为rownum> n(n>1的自然数)这种条件依旧不成立,所以查不到记录
SQL> select rownum,id,name from student where rownum >2;
ROWNUM ID      NAME
---------- ------ ---------------------------------------------------
那如何才能找到第二行以后的记录呀。可以使用以下的子查询方法来解决。注意子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。
SQL>select * from(select rownum no ,id,name from student) where no>2;
         NO ID      NAME
---------- ------ ---------------------------------------------------
          3 200003 李三
          4 200004 赵四
SQL> select * from(select rownum,id,name from student)where rownum>2;
     ROWNUM ID      NAME
---------- ------ ---------------------------------------------------

(3)rownum对于小于某值的查询条件
如果想找到第三条记录以前的记录,当使用rownum<3是能得到两条记录的。显然rownum对于rownum<n((n>1的自然数)的条件认为是成立的,所以可以找到记录。
SQL> select rownum,id,name from student where rownum <3;
     ROWNUM ID      NAME
---------- ------ ---------------------------------------------------
         1 200001 张一
         2 200002 王二
综上几种情况,可能有时候需要查询rownum在某区间的数据,那怎么办呀从上可以看出rownum对小于某值的查询条件是人为true的,rownum对于大于某值的查询条件直接认为是false的,但是可以间接的让它转为认为是true的。那就必须使用子查询。例如要查询rownum在第二行到第三行之间的数据,包括第二行和第三行数据,那么我们只能写以下语句,先让它返回小于等于三的记录行,然后在主查询中判断新的rownum的别名列大于等于二的记录行。但是这样的操作会在大数据集中影响速度。
SQL> select * from (select rownum no,id,name from student where rownum<=3 ) where no >=2;
         NO ID      NAME
---------- ------ ---------------------------------------------------
          2 200002 王二
          3 200003 李三

(4)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"

取得某列中第N大的行

select column_name from
(select table_name.*,dense_rank() over (order by column desc) rank from table_name)
where rank = &N;
 假如要返回前5条记录:

  select * from tablename where rownum<6;(或是rownum <= 5 或是rownum != 6)
假如要返回第5-9条记录:

select * from tablename
where …
and rownum<10
minus
select * from tablename
where …
and rownum<5
order by name
选出结果后用name排序显示结果。(先选再排序)

注意:只能用以上符号(<、<=、!=)。

select * from tablename where rownum != 10;返回的是前9条记录。
不能用:>,>=,=,Between...and。由于rownum是一个总是从1开始的伪列,Oracle 认为这种条件 不成立,查不到记录.

另外,这个方法更快:

select * from (
select rownum r,a from yourtable
where rownum <= 20
order by name )
where r > 10
这样取出第11-20条记录!(先选再排序再选)

要先排序再选则须用select嵌套:内层排序外层选。
rownum是随着结果集生成的,一旦生成,就不会变化了;同时,生成的结果是依次递加的,没有1就永远不会有2!
rownum 是在 查询集合产生的过程中产生的伪列,并且如果where条件中存在 rownum 条件的话,则:

1: 假如 判定条件是常量,则:
只能 rownum = 1, <= 大于1 的自然数, = 大于1 的数是没有结果的, 大于一个数也是没有结果的
即 当出现一个 rownum 不满足条件的时候则 查询结束   this is stop key!

2: 当判定值不是常量的时候
若条件是 = var , 则只有当 var 为1 的时候才满足条件,这个时候不存在 stop key ,必须进行 full scan ,对每个满足其他where条件的数据进行判定
选出一行后才能去选rownum=2的行……  

分享到:
评论
4 楼 shiguanghui 2013-10-31  
拼命的转载。你都没试过,别人的疑问你也不回答。你转来转去只是制造垃圾。
3 楼 programdolt 2013-07-04  
我最终验证了,和索引建立时间先后没关系

应该必须是“非空索引”,就是说,索引的字段不允许为空。
2 楼 programdolt 2013-07-04  
我感觉,索引必须提前建立,在数据插入前建立,这样才能符合楼主的说法。
最后建表时或表空时建立。

如果表内已经有数据,再后建立索引,应该混乱。

不知道楼主怎么看,楼主可以试试
1 楼 programdolt 2010-06-02  
"后经笔者试验,只需在order by 的字段上加主键或索引即可让oracle先按 该字段排序,然后再rownum;方法不变:
    “select * from tabname where rownum<20 order by name""

请问用的是Oracle多少,需要什么参数设置吗。 我这里用的是Oracle9i,不支持啊,依然混乱。

相关推荐

    oracle中rownum和row_number()

    row_number()over(partition by col1 order by col2)表示根据col1分组,在分组内部根据col2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)。 与rownum的区别在于:使用rownum进行排序的...

    高性能动态SQL Oracle数据安全 Oracle 数据库的聚簇技术 等等

    Oracle查询中rownum与Order by查询 45 oracle9i小结 46 Oracle 数据库的聚簇技术 61 数据库、服务名、实例 63 Oracle内存结构 64 sys用户和system用户 67 Oracle SQL语句 67 GROUPING SETS分组 74 Oracle外部程序...

    oracle与SQL server的语法差异总结

    Oracle与SQL Server应用差异对比分析在Oracle中采用伪列rownum 获取结果集中排在前面的部分记录 Eg: 返回结果集中前10条记录 Select * from sysc01 where rownum Rownum可使用&lt;、符号,不可使用&gt;、&gt;=符号,如果使用...

    Oracle数据库学习指南

    29.如何使‘CREATE TABLE AS SELECT’能支持ORDER BY 30.删除表内重复记录的方法 31.数据库安全性策略 32.数据库的查询优化技术. 33.提高C-S系统性能的一些方法 34.提高ORACLE数据库系统import性能 35....

    Oracle中使用伪列rownum实现分页查询

    伪列rownum rownum是查询返回的结果集中行的序号,可以使用它来限制查询返回的行数 ...select * from emp order by sal desc ) where rownum&lt;=3 结果如下: 原创文章 4获赞 4访问量 62 关注 私信

    Oracle 9i与MS SQL Server 2000之比较

    在SQL Server中可以用top n 来返回指定数量的纪录,Oracle中与之对应的是 rownum,只 是不同的是:SQL Server的top n 是逻辑顺序返回的纪录,而Oracle的 rownum 指定的是物理顺 序的序号,其物理的序号是在order by之前就...

    Oracle练习.txt

    ORDER BY column; 15. 如何在给现有的日期加上2年? select add_months(sysdate,24) from dual; 16.Connect string是指什么? 应该是tnsnames.ora中的服务名后面的内容 17.返回大于等于N的最小整数值? SELECT CEIL(-...

    在ORACLE中SELECT TOP N的实现方法

     由于ORACLE不支持SELECT TOP语句,所以在ORACLE中经常是用ORDER BY跟ROWNUM的组合来实现SELECT TOP N的查询。  简单地说,实现方法如下所示: SELECT 列名1...列名n FROM (SELECT 列名1...列名n...

    Oracle数据库、SQL

    5.4 order by后面可以跟什么 10 5.5多列排序 10 六、 单行函数的使用 11 6.1数值类型 11 6.2日期类型 11 6.3字符类型 13 6.4转换函数 14 6.5其他注意事项 14 七、 SQL语句中的分支 15 7.1分支表达式 15 7.2分支函数 ...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    从就业与择业的角度来讲,计算机相关专业的大学生从事oracle方面的技术是职业发展中的最佳选择。 其一、就业面广:全球前100强企业99家都在使用ORACLE相关技术,中国政府机构,大中型企事业单位都能有ORACLE技术的...

    Oracle与Mysql主键、索引及分页的区别小结

    3、分页, mysql: select * from user order by desc limit n ,m. 表示,从第n条数据开始查找,一共查找m条数据。 Oracle:select * from user select rownum a * from ((select * from user)a) select * from ...

    根据时间拆分记录的方法

    WITH t2 AS (SELECT ROWNUM-1 rn FROM dual CONNECT BY ROWNUM(SELECT MAX( ceil(months_between(e_date,s_date)))+1 FROM URP_WAGE.T_WAGE_BASE_ITEM_BKYM)) SELECT employee_id,year_month, Add_months(s_date,...

    Oracle创建视图(View)

    2.在没有WITH CHECK OPTION和 READ ONLY 的情况下,查询中不能使用ORDER BY 子句; 3.如果没有为CHECK OPTION约束命名,系统会自动为之命名,形式为SYS_Cn; 4.OR REPLACE选项可以不删除原视图便可更改其定义并...

    Oracle事例

    SQL&gt;select index_name,index_type,table_name from user_indexes order by table_name; 、查看索引被索引的字段 SQL&gt;select * from user_ind_columns where index_name=upper(\'&index_name\'); 11、创建序列 ...

    Oracle 随机数

    利用oracle的dbms_random包结合rownum来实现,示例如下,随机取499户: select * from ( select * from busi.t_ar_userinfo order by dbms_random.value) where rownum &lt; 500; 有关dbms_random的参考文献,链接...

    oracle教案(doc)+SQL Reference 10g(chm).rar

    3.2.4 对查询结果进行排序 ORDER BY 子句 (重点) 24 3.2.5 单行函数 (重点) 26 3.2.6 SQL语句强化训练 39 3.2.7 多表查询 40 3.2.8 组函数及分组统计 (重点) 52 3.2.9 子查询 58 3.2.10 ROWNUM伪列(重点) 63 3.2.11 ...

    Oracle实现分页查询的SQL语法汇总

    1.无ORDER BY排序的写法。(效率最高) 经过测试,此方法成本最低,只嵌套一层,速度最快!即使查询的数据量再大,也几乎不受影响,速度依然! sql语句如下: SELECT * FROM (Select ROWNUM AS ROWNO, T.* from k_...

    深入探讨:oracle中row_number() over()分析函数用法

    row_number()over(partition by col1 order by col2)表示根据col1分组,在分组内部根据col2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)。 与rownum的区别在于:使用rownum进行排序的...

    mysql, oracle等常见数据库的分页实现方案

     select top @pagesize * from tablename where id not in (select top @pagesize*(@page-1) id from tablename order by id) order by id  3.MySQL  select * from tablename limit posi

    Oracle 分析函数RANK(),ROW_NUMBER(),LAG()等的使用方法

    ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,在分组内部根据 COL2排序 而这个值就表示每组内部排序后的顺序编号(组内连续的唯一的) RANK() 类似,不过RANK 排序的时候跟派名次一样,...

Global site tag (gtag.js) - Google Analytics