项目数据库 MySQL → Oracle,记录一下 Oracle 的分页实现
ROWNUM
与 MySQL 不同,Oracle 中没有 LIMIT 关键字,分页的实现是利用 ROWNUM
ROWNUM 是 Oracle 给查询返回的行添加的顺序编号,从 1 开始向后递增,用于显示行号, ROWNUM 不能以任何表的名称作为前缀
基本用法
SELECT T.* FROM USER T
NAME | AGE |
---|---|
张三 | 19 |
李四 | 22 |
王五 | 20 |
SELECT T.*, ROWNUM FROM USER T
NAME | AGE | ROWNUM |
---|---|---|
张三 | 19 | 1 |
李四 | 22 | 2 |
王五 | 20 | 3 |
过滤行号
ROWNUM 对于< N(正整数)的条件认为是成立的
SELECT T.*, ROWNUM FROM USER T WHERE ROWNUM < 3
NAME | AGE | ROWNUM |
---|---|---|
张三 | 19 | 1 |
李四 | 22 | 2 |
但当条件为 ROWNUM > N(正整数)时是查不出来记录的,因为 ROWNUM 是一个从 1 开始的伪列,当第一条不满足的话,第二条的 ROWNUM 又成了 1,以此类推,永远不会有满足条件的记录
SELECT T.*, ROWNUM FROM USER WHERE ROWNUM > 2
NAME | AGE | ROWNUM |
---|---|---|
搭配 ORDER BY
如果把刚刚的查询按照 AGE 进行排序,ROWNUM 会出现乱序的情况
SELECT T.*, ROWNUM FROM USER T ORDER BY AGE
NAME | AGE(无索引) | ROWNUM |
---|---|---|
张三 | 19 | 1 |
王五 | 20 | 3 |
李四 | 22 | 2 |
在 SELECT 语句中有 ORDER BY,ORDER BY 一般都在最后一步执行。但如果 ORDER BY 子句里的字段被设置了主键约束或是被设置索引,那么 ORDER BY 执行之后,会重新对结果集的 ROWNUM 值进行编号
NAME | AGE(有索引) | ROWNUM |
---|---|---|
张三 | 19 | 1 |
王五 | 20 | 2 |
李四 | 22 | 3 |
分页实现
通常情况下 ORDER BY 的字段不一定都带有索引,所以要实现分页的话需要进行嵌套
SELECT * FROM
( SELECT T1.*, ROWNUM RN FROM
( SELECT * FROM USER ORDER BY AGE ) T1
) T2
WHERE T2.RN > start AND T2.RN <= end
注意
ROWNUM 在使用时表名必须带别名