`
BBjava
  • 浏览: 125513 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

rownum in ORACLE

阅读更多
  ORACLE中的rownum
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/mitedu/archive/2008/12/22/3584399.aspx

(要看图片请到原贴处)



1 引言

Oracle中的rownum一般是在实现分页查询时用到,虽然在我做的项目中只实现了分页显示而没有实现真正的分页,但是出于学习的目的研究了一下oracle的rownum。在使用查询语句时,我们经常要求返回表中的前n条记录或者是中间的几条记录,比如在一个大表(假设有10W条数据)要求查询从第1000到1005条的记录。面对这种查询,我们怎么办呢?mysql和oracle都有自己的解决办法。

2 MySql中的实现
在mysql中,我们可以使用limit语句来实现:

1)查询从第1000到1005条的记录(注意mysql中的记录是从0开始编号的,所以第1000条记录编号为999)

select * from table_name limit 999,5;
2)查询前10条记录

select * from table_name limit 10;
等价于:
select * from table_name limit 0,10;
2)查询从第100条记录开始到表的最后一条记录

select * from table_name limit 99 -l;
mysql提供-L的参数,表示到表的最后一条记录

3 Oracle中的实现
Oracle使用rownum的关键字来实现这种查询:

首先我们假设有一个地域信息表area,其表结构如下图所示:




表中的数据如下图所示(select * from area语句得到的结果):






1)查询表中的前8条记录
select * from area where rownum <= 8
查询结果如下:







2)查询第2到第8条记录
对于这种形式的查询,oracle不像mysql那么方便,它必须使用子查询或者是集合操作来实现。我们可以使用以下3种方式可以实现:

A: select id,province,city,district from (select id,province,city,district,rownum as num from area) where num between 2 and 8;
首先根据select id,province,city,district,rownum as num from area得到一个临时表,这个临时表中有一个rownum列(一个伪列,类似与rowid,但又不同于rowid,因为rowid是物理存在的一个列,也就是说Oracle数据库中任何一个表都有一个rowid列,而rownum不是物理存在的),然后在临时表中来查询。
B: select * from area where rownum <= 8 minus select * from area where rownum < 2;
使用集合减运算符minus,该操作返回在第一个select中出现而不在第二个select中出现的记录。
C: select id,province,city,district from (select id,province,city,district,rownum as num from area) where num >=2
intersect
select * from area where rownum <= 8;
使用集合交运算符intersect,这里绕了一个弯(不过这个弯实现了rownum大于某个数的查询),它是首先利用A的方式查询得到所有rownum大于2的记录,然后再与rownum小于等于8的记录集合做交运算。三种操作得到的结果一样,如下图所示:







3)rownum需要注意的问题

[1] rownum不支持以下方式的查询

a: select * from area where rownum > 2;
b: select * from area where rownum = n;  --where n is a integer number lager than 1
注:rownum只支持select * from area where rownum =1的查询。Oracle的官方文档说明如下:

Conditions testing for ROWNUM values greater than a positive integer are always false.

For example, this query returns no rows:

SELECT * FROM employees

WHERE ROWNUM > 1;

The first row fetched is assigned a ROWNUM of 1 and makes the condition false. The

second row to be fetched is now the first row and is also assigned a ROWNUM of 1 and

makes the condition false. All rows subsequently fail to satisfy the condition, so no

rows are returned.

因为rownum是根据查询的结果集来对记录进行编号,所以当你查询rownum大于2的记录时会得到一个空的结果集。因为当oracle查询得到第1条记录时,发现rownum为1不满足条件,然后就继续查询第2条记录,但此时第2条记录又被编号为1(也即rownum变为1),所以查询得到的始终是rownum=1,因此无法满足约束,最终查询的结果集为空。



[2] rownum的排序查询问题

Rownum的排序查询是根据表中数据的初始顺序来进行的。Oracle官方文档中说明如下:

If an ORDER BY clause follows ROWNUM in the same query, then the rows will be

reordered by the ORDER BY clause. The results can vary depending on the way the

rows are accessed. For example, if the ORDER BY clause causes Oracle to use an index

to access the data, then Oracle may retrieve the rows in a different order than without

the index.

例如:select * from area where rownum <= 8 order by district;
其结果如下图所示:




发现没有,它只对area表中的前8条记录进行排序。那么,如果我要取表中的前8条记录并且要求是全表有序,那怎么办呢?还是老办法,使用子查询。我们可以使用以下语句得到:
select * from (select * from area order by district)

where rownum <= 8;
查询的结果如下图所示:





4 结束语
Oracle中的rownum与mysql的limit实现的功能相同,但没有mysql来的容易,它一般通过一个子查询来实现。mysql的易用性也是它能够纵横开源数据库的原因,它不像postgresql那样的学院派,它的那种简单易用性或许在大型软件项目的开发中值得借鉴。最近听说sql server 2008也实现了limit的查询,不过还没去试过,Oracle在这方面也要加油啊,用户容易使用才是王道


分享到:
评论

相关推荐

    基于jsp+servlet、使用原生ajax,实现单表增删改查、文件上传、条件查询和分页

    Servlet会计算分页所需的SQL(例如,LIMIT和OFFSET在MySQL中,或者ROWNUM in Oracle中),返回指定页的数据,并在前端显示。 8. **Oracle数据库**:Oracle是一种关系型数据库管理系统,广泛应用于企业级应用。在这...

    Oracle数据库中ORDER BY排序和查询按IN条件的顺序输出

    本文将深入探讨`ORDER BY`子句在Oracle中的排序机制,以及查询时根据`IN`条件顺序输出的方法。 首先,`ORDER BY`用于指定查询结果的排序方式,可以基于一个或多个列进行升序(ASC)或降序(DESC)排序。然而,...

    Oracle中如何用一条SQL快速生成10万条测试数据

    ROWNUM是Oracle中的一个伪列,用于返回行的顺序号,从1开始递增。在生成测试数据时,ROWNUM可以帮助我们控制生成记录的数量。CONNECT BY LEVEL则是一种递归查询的方法,可以用来生成连续的行,直到LEVEL的值达到指定...

    DM8与Oracle12c兼容性白皮书.pdf

    目前,大多数应用程序使用的是Oracle数据库,而用户或多或少的使用了Oracle的...Oracle兼容性方面实现的功能包括:ROWNUM表达式、多列IN语法、层次查询、外连接语法“(+)”、INSTEADOF触发器、%TYPE以及记录类型等

    dbms.rar_Sql queries_in_oracle queries

    5. **排序与分页**:ORDER BY语句用于对查询结果进行排序,LIMIT或ROWNUM(Oracle特有)用于限制返回的行数,实现分页效果。 6. **视图**:视图是虚拟表,由一个或多个SQL查询定义,可以简化复杂的查询并保护数据。...

    Oracle数据库通用的分页存储过程

    Oracle数据库中实现分页查询主要有两种方法:ROWNUM和ROW_NUMBER()函数,这里我们主要讨论通过存储过程实现的通用分页方法。 一、ROWNUM方法 ROWNUM是Oracle数据库中的一个伪列,它会为每一行分配一个唯一的整数,...

    Oracle 存储过程分页

    在早期的Oracle版本中,ROWNUM伪列被广泛用于分页。ROWNUM是在结果集生成时自动分配的,表示每一行的顺序号。例如,以下存储过程展示了基于ROWNUM的分页查询: ```sql CREATE OR REPLACE PROCEDURE get_paged_...

    java笔记\Oracle里sql不能用limit的处理

    在Oracle中,我们可以使用RowNum函数来实现分页查询。RowNum函数可以返回当前记录的行号,从1开始。我们可以使用RowNum函数来限制查询的记录数。 例如,以下SQL语句可以查询表t_table_name的前10条记录: ```sql ...

    Oracle的SQL分页实践.pdf

    本文将详细介绍Oracle数据库中SQL的分页实践,特别是利用Oracle的rownum伪列和游标(Cursor)进行分页操作的技术。 首先,我们需要了解rownum在Oracle SQL查询中的作用。rownum是Oracle特有的一个伪列,它表示了...

    Sql语法转换为Oracle语法

    3. 子查询:SQL Server使用 `IN (SELECT ...)`,Oracle则更倾向于 `EXISTS (SELECT 1 FROM ...)`。 4. 分页查询:SQL Server 使用 `OFFSET ... ROWS FETCH NEXT ... ROWS ONLY`,Oracle则使用 `ROWNUM` 和子查询来...

    oracle与SQL server的语法差异总结

    在Oracle中,ROWNUM是一个伪列,用于获取结果集中的部分记录。例如,`SELECT * FROM sysc01 WHERE ROWNUM 会返回前10条记录。ROWNUM只能使用小于等于(&lt;, )符号,不能使用大于等于(&gt;, &gt;=),并且如果使用等号(=...

    oracle到sqlserver存储过程语法转换

    - **Oracle**: 使用`ROWID`和`ROWNUM`进行行标识和计数。 ```sql SELECT * FROM table WHERE ROWNUM ; ``` - **SQL Server**: 使用`TOP`来限制返回的行数。 ```sql SELECT TOP 10 * FROM table; ``` **5. ...

    Oracle PL SQL 开发人员试题(DBA)

    Oracle PL/SQL 开发人员试题...本资源涵盖了 Oracle PL/SQL 中的多个重要概念和语句,包括子查询、NOT IN 语句、EXISTS 语句、IN 语句和 ROWNUM 语句等。这些概念和语句是 Oracle PL/SQL 开发人员必须掌握的基本技能。

    oracle 高效分页

    在Oracle中,`ROW_NUMBER()`和`ROWNUM`是实现分页查询的两种主要方式。其中,`ROW_NUMBER()`函数是在SQL标准中的窗口函数,它可以为每一行分配一个唯一的行号,而这个行号的顺序可以基于某一列的排序规则。`ROWNUM`...

    Oracle中如何用一条SQL快速生成10万条测试数据.txt

    为了模拟真实场景中的日期时间数据,我们使用`SYSDATE`函数加上`ROWNUM`除以一天的秒数(24*3600)的方式,生成了一个随着时间递增的日期时间字段(`INC_DATETIME`)。这样可以确保每一条记录的时间都是递增的,并且...

    Oracle All 添加 修改 更新 Oracle分页 emp表 存储过程实现

    在Oracle中,我们可以利用ROWNUM伪列配合子查询来实现分页。 以下是一个简单的分页查询存储过程的实现步骤: 1. **创建存储过程**: 在Oracle中,创建存储过程的语法如下: ```sql CREATE OR REPLACE PROCEDURE...

    oracle上机练习题

    - 分页:使用`ROWNUM`配合子查询实现分页查询,如`SELECT * FROM (SELECT * FROM table WHERE ROWNUM ) WHERE ROWNUM &gt; limit;`。 4. **Oracle特有功能**: - PL/SQL:Oracle的面向过程的编程语言,用于编写存储...

    oracle的伪列与分页

    Oracle提供了一些内置的伪列供用户使用,如`ROWID`和`ROWNUM`等,这些伪列可以帮助开发人员更方便地进行查询、排序等操作。 #### 二、ROWID与ROWNUM详解 **ROWID:** - **定义**:ROWID是Oracle中用于唯一标识表中...

    oracle与mysql的区别

    语句一:SELECT ID, [FIELD_NAME,...] FROM TABLE_NAME WHERE ID IN ( SELECT ID FROM (SELECT ROWNUM AS NUMROW, ID FROM TABLE_NAME WHERE 条件 1 ORDER BY 条件 2) WHERE NUMROW &gt; 80 AND NUMROW ) ORDER BY 条件...

    oracle面试题

    以上就是关于Oracle中`RowID`、`RowNum`的使用方法,以及Oracle分页语句和存储过程的创建与使用的详细介绍。这些知识点对于Oracle开发人员来说非常重要,熟练掌握它们能够帮助你在实际工作中更高效地解决问题。

Global site tag (gtag.js) - Google Analytics