ITPub博客

首页 > 数据库 > Oracle > 分页语句该怎么写?

分页语句该怎么写?

原创 Oracle 作者:a960549548 时间:2024-03-29 08:55:58 0 删除 编辑

为了便于在网页中的显示,常常需要分页显示,比如要求员工表 emp 按工资排序后一次只显示 5 行数据,下面以第二页数据为例进行分页。

 

生成序号前,先对数据进行排序,然后再在外层生成序号,这样序号才不会乱:

 

/* 先对数据根据 sal 做排序 */

select sal, ename from emp where sal is not null order by sal

NIX"] Ogal  0081  HIDE  0091  IVS  Sm D96  0011  SAN 6Z  O 凵 S 0008  SINN 0009  Ogal  0008

 

/* 然后根据排序后的数据生成序号,并过滤掉前十行以后的数据 */

select rownum as rn, sal, ename
  from (select sal, ename from emp where sal is not null order by sal)
 where rownum <= 10

NIX"] Ogal  0081  HIDE  0091  IVS  Sm D96  0011  Ogal

 

/* 根据序号过滤掉前 6 行以前的数据 */

select rn as 序号, sal as 工资, ename as 姓名
  from (select rownum as rn, sal, ename
          from (select sal, ename from emp where sal is not null order by sal)
         where rownum <= 10)
 where rn >= 6

'LLLLL

 

为什么不直接用 rownum <= 10 and rownum >= 6 而是要分开写?先看看下面的比对结果。

select count(*) from emp where rownum <= 10

select count(*) from emp where rownum <= 10 and rownum >= 6

 

因为 rownum 是伪列,他必须要先有数据, rownum 才会有值,因此执行 and rownum >= 6 时,始终无法获取前十行数据,因此 rownum <= 10 and rownum >= 6 查询不到数据,所以需要先在子查询中取出数据,再 where rn >= 6 过滤一次。

 

或者也可以用 row_number() 分析函数生成序号在过滤,这样只要嵌套一次,但不推荐这么做,因为分页语句的特殊性,有些索引和执行计划可能会受分析函数影响不能使用,因此还是建议用第一个方式,套用模板。

select rn as 序号, sal as 工资, ename as 姓名
  from (select row_number() over(order by sal) as rn, sal, ename
          from emp
         where sal is not null)
 where rn >= 6
   and rn <= 10

 


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70013625/viewspace-3010821/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
Oracle ACE,MySQL 8.0 OCP,PMP,拥有OceanBase OBCP,TiDB PCTP,GoldenDB GDCP等多项认证,ITPUB认证专家,微信公众号:DBA之友。

注册时间:2022-02-08

  • 博文量
    132
  • 访问量
    171527