Oracle 中的 SQL 分页查询原理和方法详解

本文分析并介绍 Oracle 中的分页查找的方法。sql

    Oracle 中的表,除了咱们建表时设计的各个字段,其实还有两个字段(此处只介绍2个),分别是 ROWID(行标示符)和 ROWNUM(行号),即便咱们使用DESCRIBE命令查看表的结构,也是看不到这两个列的描述的,由于,他们实际上是只在数据库内部使用的,因此也一般称他们为伪列(pseudo column)。数据库

    下面咱们先建表并添加一些数据来验证上面的说明。优化

     建表:编码

create table users(
id integer primary key,
name nvarchar2(20)
)

 

    插入数据:spa

 

insert into users(id,name) values(1,'tom');
insert into users(id,name) values(2,'cat');
insert into users(id,name) values(3,'bob');
insert into users(id,name) values(4,'anxpp');
insert into users(id,name) values(5,'ez');
insert into users(id,name) values(6,'lily');

 

  1. 使用describe命令查看表结构:

    能够看到,确实只有建表时的两个字段。.net

    但咱们能够查询的时候,查找到伪列的值:设计

select rowid,rownum,id,name from users;

    结果:code

   

    这个 rowid 咱们通常用不到,Oracle 数据库内部使用它来存储行的物理位置,是一个 18 位的数字,采用 base-64 编码。blog

    而这个 rownum,咱们也正是使用它来进行分页查询的,它的值,就是表示的该行的行号。排序

    对于分页,咱们只要想办法能够查询到从某一块儿始行到终止行就能够的,分页的逻辑能够放到程序里面。

    因而,咱们理所固然会想到以下语句查询第 2 页的数据(每页2条数据,页码从 1 开始,因此起始行的行号为 (页码-1) * 每页长度 +1=3,终止行的行号为 页码*每页长度=4 )。

select * from users where rownum>=3 rownum <= 4;

    哈哈!是否是发现没有任何结果,缘由很简单,Oracle机制就是这样的:由于第一条数据行号为1,不符合>=3的条件,因此第一行被去掉,以前的第二行变为新的第一行(即这个行号不是写死的,能够理解为是动态的),如此下去,一直到最后一行,条件始终无法知足,因此就一条数据也查不出来。

    既然找到了缘由,解决方法也就很明显了,咱们只要将行号查询出来生成一个结果集,而后再从这个结果集中,选择行号大于咱们设定的那个值就能够了,上面的分页查找正确的写法应该是这样:

select id,name from(
select rownum rn,u.* from users u) ua
where ua.rn between 3 and 4;

    上面的语句还能够优化:>= 不能用,可是 <= 是能够的,咱们不须要在子查询中将结果所有查出来,首先使用终止行筛选子查询的结果,SQL以下:

select id,name from(
select rownum rn,u.* from users u where rownum<=4) ua
where ua.rn >= 3;

    结果:

   

    不少时候,咱们并非盲目的分页查找的,二十按某一个或多个字段的升序或降序分页,即包含 order by 语句的分页查询,咱们先看一下 order by 的查询结果中 rownum 是怎样的:

select rownum,id,name from users order by name;

    结果:

   

    能够看到,咱们说行号彻底是动态的,也是不许确的,这时候的行号并非通过 order by 后新结果的增序行号。

    但有了上面的嵌套查询的经验,这里也能够好好应用一下,怎么作呢:先查找出排序好的结果集,而后应用上面的方法获得最终结果,sql 以下:

select id,name from(
(select rownum rn,uo.* from
(select * from users u order by name) uo
where rownum<=4)) ua
where ua.rn>=3;

    按照上面的结果,正确的分页结果应该是 id 为 2 和 5 的,看下结果:

   

    OK,结果正确。

    其实连表查询之类的,也是差很少的,多点嵌套而已,掌握了原理,随便分析一下就能写出对应的 SQL 了,而编写 SQL 时,咱们也得动动脑子,毕竟 SQL 也是由优劣之分的。

 

原文写得很好能够看下!

本文转载自:http://blog.csdn.net/anxpp/article/details/51534006

相关文章
相关标签/搜索