分页语句该怎么写?

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

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

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

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

分页语句该怎么写?_第1张图片
/然后根据排序后的数据生成序号,并过滤掉前十行以后的数据/

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

分页语句该怎么写?_第2张图片
/根据序号过滤掉前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;

在这里插入图片描述
为什么不直接用 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;

在这里插入图片描述

你可能感兴趣的:(SQL,Turning,数据库,oracle,dba,数据库开发,windows)