zoukankan      html  css  js  c++  java
  • oracle中的rownum、order by与分页

    先看以下两条语句的执行结果:

    语句一:select rownum,empno,sal from emp order by empno;

        ROWNUM      EMPNO        SAL
    ---------- ---------- ----------
             1       7369        800
             2       7499       1600
             3       7521       1250
             4       7566       2975
             5       7654       1250
             6       7698       2850
             7       7782       2450
             8       7788       3000

      ……

    语句二:select rownum,empno,sal from emp order by sal;

        ROWNUM      EMPNO        SAL
    ---------- ---------- ----------
             1       7369        800
            12       7900        950
            11       7876       1100
             3       7521       1250
             5       7654       1250
            14       7934       1300
            10       7844       1500
             2       7499       1600

        ……

    同样的两个语句,执行结果中的rownum伪列的值却大相径庭,这是什么原因呢?

    其实这都是ORACLE内部的查询优化器和索引搞的鬼!

    rownum伪列产生的序号是按照数据被查询出来的顺序添加上去的,第一条是1,第二条是2,依次加1。

    当将一条语句交给查询优化器处理时:

    如果排序列上有索引,则借助索引去查询数据,这样,读取出来的数据和rownum产生的序号是一种正常的对应关系,如语句一的结果(empno上有主键索引)。

    如果排序列上没有索引,则使用全表扫描的方式,依次从表中读取数据,读取完成后,最后进行排序,于是产生了类似语句二的结果(sal列上没有索引)。

    正是由于排序列上不一定有索引,所以在ORACLE中使用rownum伪列分页时,需要多加一层查询,以保证rownum序号的连续性。

    语句三:select rownum,t.* from
    (select empno,sal from emp order by sal) t;

        ROWNUM      EMPNO        SAL
    ---------- ---------- ----------
             1       7369        800
             2       7900        950
             3       7876       1100
             4       7521       1250
             5       7654       1250
             6       7934       1300
             7       7844       1500
             8       7499       1600

           ……

    这个结果还满意吧。。。

    分页:在外面再加上一层查询。

    select * from
    (select rownum num,t.* from
    (select empno,sal from emp order by sal) t)
    where num between 6 and 10;

    当然,如果使用分析函数row_number就可以省略一层查询了,代码更简单点:

    select * from
    (select row_number() over (order by sal) num,empno,sal from emp)
    where num between 6 and 10;

  • 相关阅读:
    【Hadoop】HDFS客户端开发示例
    【Hadoop】HDFS原理、元数据管理
    【Linux】pv vg lv, 加盘,扩容磁盘
    【Hadoop】伪分布式环境搭建、验证
    【Docker安全】关于Docker使用root与非root用户的场景中的容器与host中的执行用户的研究
    【监控】使用 Grafana、collectd 和 InfluxDB 打造现代监控系统
    【网络】再谈select, iocp, epoll,kqueue及各种I/O复用机制 && Reactor与Proactor的概念
    【Hadoop】用 Ganglia 监控hadoop集群
    【自动部署】服务器自动化操作 RunDeck
    springmvc不通过controller进行页面跳转
  • 原文地址:https://www.cnblogs.com/lgzslf/p/1747469.html
Copyright © 2011-2022 走看看