Oracle 的分页查询~~~ROWNUM(行号)

一、Oracle 的分页

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

select rowid,rownum,id,col from table;

这个 rowid 一般用不到,Oracle 数据库内部使用它来存储行的物理位置,是一个 18 位的数字,采用 base-64 编码。而这个 rownum,正是用来进行分页查询的,它的值,就是表示的该行的行号。
对于分页查询,只要想办法查询从某一起始行到终止行就可以的,分页的逻辑可以放到程序里面。于是,理所当然会想到如下语句查询第 2 页的数据(每页 2 条数据,页码从 1 开始,所以起始行的行号为(页码-1)*每页长度+1=3,终止行的行号为页码*每页长度=4

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

出人意料,没有任何结果。原因很简单,Oracle 机制就是这样的:因为第一条数据行号为 1,不符合 >=3 的条件,所以第一行被去掉,之前的第二行变为新的第一行(即该行号不是写死的,可以理解为是动态的),如此下去,一直到最后一行,条件始终没法满足,所以就一条数据也查不出来。
对症下药,要想解决这个问题,只要将行号查询出来生成一个结果集,然后再从这个结果集中,选择行号大于设定的那个值就可以了,上面的分页查找正确的写法应该是这样:

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

上面的语句还可以优化:虽然不能用“>=”但“<=”却可以用。为提高查询效率,可以使用终止行筛选子查询的结果,SQL 如下:

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

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

select rownum,id,col from table order by col;

结果,此时的行号并不是经过 order by 后结果的增序行号。
但有了上面的嵌套查询的经验,这里也可以好好应用一下,怎么做呢:先查找出排序好的结果集,然后应用上面的方法得到最终结果,sql 如下:

SELECT
    id,col 
FROM
    ( SELECT rownum rn, uo.* FROM ( SELECT * FROM TABLE ORDER BY col ) uo WHERE rownum <= 4 ) ua 
WHERE
    ua.rn >= 3;

二、分页效果的实现,思路有三种

  1. 纯 JS 实现分页。一次性查询记录并加载到 html 的 table 中。然后通过选择性地显示某些行来达到分页显示的目的。这是一种伪分页,障眼法而已。只能用于数据少的情况下。一旦数据多了,十几万条数据加载到 html 中会变得很慢。而且不实时,一次加载完后数据就写死在页面了,若数据库中有变化,浏览器端显示的仍是上次加载过来的数据。

  2. 一次查询,分批显示。
    就是说,可以执行一个数据库查询操作,得到结果集 rs。然后,通过指针的移动来显示当前页面的记录。这样,就可以以 rs.absolute(当前页面号*每页记录数)定位到当前页的第一条记录,然后通过 while 循环显示 n 条记录(n 为每页显示记录数)。在跳页时,只需修改 currentPage,即可在重定位到下一页时把当前页面号改掉,重新定位记录指针,通过 while 遍历显示 n 条记录。与 JS 选择性显示不同,这里是选择性遍历。与 JS 分页不同的是,这里分页每次跳页修改的是遍历的指针,每次跳页都要进行一次全面查询。同样地,不适合大数据量查询。这里比 JS 分页优化的地方在于——实时性。每次跳页都会查询一次数据库,保证数据的实时性。

  3. 在服务端分页。跳到第 n 页才查询、显示第 n 页内容。要点就是根据客户端表格的“页面”计算出数据库要查询的当前页面的第一条记录的位置。优点:实时性:跳页才查询。数据量小:只加载当前页的记录进行显示。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容