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

Oracle中的SQL分页查询原理和方法详解转载请注明出处:http://blog.csdn.net/anxpp/article/details/51534006,谢谢!  本文分析并介绍Oracle中的分页查找的方法。  Oracle中的表,除了我们建表时设计的各个字段,其实还有两个字段(此处只介绍2个),分别是ROWID(行标示符)和ROWNUM(行号),即使我们使用DESCRIBE命令查看表的结构,也是看不到这

大家好,又见面了,我是你们的朋友全栈君。

转载请注明出处:http://blog.csdn.net/anxpp/article/details/51534006,谢谢!

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

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

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

    建表:

 
 
 
  1. create table users(
  2. id integer primary key,
  3. name nvarchar2(20)
  4. )

    插入数据:


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

    使用describe命令查看表结构:

    01

    可以看到,确实只有建表时的两个字段。

    但我们可以查询的时候,查找到伪列的值:


  
  
  
  1. select rowid,rownum,id,name from users;

    结果:

    02

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

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

    对于分页,我们只要想办法可以查询到从某一起始行到终止行就可以的,分页的逻辑可以放到程序里面。

    于是,我们理所当然会想到如下语句查询第2页的数据(每页2条数据,页码从1开始,所以起始行的行号为 (页码-1)*每页长度+1=3,终止行的行号为 页码*每页长度=4):


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

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

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


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

    上面的语句还可以优化:>=不能用,但是<=是可以的,我们不需要在子查询中将结果全部查出来,首先使用终止行筛选子查询的结果,SQL如下:


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

    结果:

    03

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


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

    结果:

    04

    可以看到,我们说行号完全是动态的,也是不准确的,这时候的行号并不是经过 order by 后新结果的增序行号。

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


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

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

    05

    OK,结果正确。

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/153263.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • cmd查询MySQL版本_mysql数据库卸载

    cmd查询MySQL版本_mysql数据库卸载mysql-v

    2022年10月6日
    0
  • 谷歌浏览器驱动国内镜像下载地址[通俗易懂]

    谷歌浏览器驱动国内镜像下载地址[通俗易懂]谷歌驱动(driverchrome.exe)国内镜像下载地址:http://npm.taobao.org/mirrors/chromedriver/Windows、Linux、MAC系统均可下载下载解压,放到C:\ProgramFiles(x86)\Google\Chrome\Application(自己的谷歌浏览器安装路径)下即可…

    2022年6月7日
    213
  • 使用cJSON解析JSON字符串

    使用cJSON解析JSON字符串使用cJSON解析JSON字符串一、为何选择cJSON;二、cJSON的核心结构体;三、解析JSON格式;1,下载源码;2,包含cJSON的源码;3,解析一个键值对;4,解析一个结构体; 5,解析结构体数组的JSON串;附带例程;

    2022年6月29日
    76
  • rsyslogd 重启_rsyslogd配置文件详解

    rsyslogd 重启_rsyslogd配置文件详解rsyslog服务和logrotate服务======================================================================rsyslog是一个syslogd的多线程增强版。现在Fedora和Ubuntu,rhel6默认的日志系统都是rsyslog了rsyslog负责写入日志,logrotate负责备份和删除旧日志,以及更新日志…

    2022年8月15日
    3
  • Android P 新特性抢先看[通俗易懂]

          上周的世界移动通信大会上,我们看到了安卓开发者,设备生产者和芯片合作者组成的安卓生态系统不断的给用户代码惊喜的体验。      新特性下面就来看看AndroidP第一个预览版的一些很酷的特性。      1,Wi-Fi室内定位      精确的室内定位一直以来都是一个挑战,它给lbs创造了新的机遇。AndroidP支持了IEEE802.11mcWi-Fi协议,…

    2022年4月14日
    39
  • 阿里云动态域名_阿里动态域名解析

    阿里云动态域名_阿里动态域名解析前言该脚本的代码大部分是参考自阿里云的官方帮助文档。1,脚本语言使用的是python,我个人只是了解python,没有太深入的知识功底2,脚本代码我会尽量详细地添加注释说明,有问题欢迎留言

    2022年8月5日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号