Oracle数据库的 Top-N 分析和 分页查询。ROWNUM伪列,详细笔记。

文章目录

  • 1. Top-N分析
    • 1.1 什么是Top-N分析
    • 1.2 执行Top-N分析
  • 2. Oracle数据库的分页查询

备注:本文中使用到的sql为HR用户提供的数据和表。HR用户介绍查看以下链接。
https://blog.csdn.net/weixin_45842494/article/details/122528264

1. Top-N分析

1.1 什么是Top-N分析

Top-N查询需要基于一个条件,从表中显示最前面的n条记录或最后面的n条记录时是有用的。该结果可以用于进一步分析,例如,用Top-N 分析你可以执行下面的查询类型:

  • 公司中挣钱最多的三个
  • 公司中最新的四个人
  • 销售产品最多的两个销售代表
  • 过去6个月中销售最好的3种产品

说得简单一点就是排名。

1.2 执行Top-N分析

Top-N查询使用一个带有下面描述的元素的一致的嵌套查询结构:

  • 子查询或者内建视图产生数据的排序列表,该子查询或者内建视图包含ORDERBY子句来确保排序以想要的顺序排列。为了取回最大值,需要用DESC参数。
  • 在最后的结果集中用外查询限制行数。外查询包括下面的组成部分:
    • ROWNUM伪列,它为从子查询返回的每一行指定一个从1开始的连续的值
    • 一个WHERE子句,它指定被返回的n行,外WHERE子句必须用一个 < 或者 <= 操作。
select rownum ,last_name from employees;
返回:
    ROWNUM LAST_NAME
---------- -------------------------
         1 Abel
         2 Ande
         3 Atkinson
		...
       109 Whalen
       110 Zlotkey
110 rows selected

说明:rownum并不是表中的列,只是我们为了排序加了rownum,会从1开始,将我们查询到的数据进行排序。

示例一:

从EMPLOYEES表中显示挣钱最多的3个人的名字及其薪水。

select rownum,last_name,salary from (select salary,last_name from employees order by salary desc) where rownum <= 3;
返回:
    ROWNUM LAST_NAME                     SALARY
---------- ------------------------- ----------
         1 King                        24000.00
         2 Kochhar                     17000.00
         3 De Haan                     17000.00

示例二:

显示公司中4个资格最老的雇员,显示他们的入职时间和名字。

select rownum,e.last_name,e.hire_date from (select last_name, hire_date from employees order by hire_date) e where rownum <= 4;
返回:
    ROWNUM LAST_NAME                 HIRE_DATE
---------- ------------------------- -----------
         1 De Haan                   2001/1/13
         2 Mavris                    2002/6/7
         3 Higgins                   2002/6/7
         4 Baer                      2002/6/7

分析:子查询(内建视图)帮我们查询到了我们需要的入职时间和名字并排好序,主查询是在排好序的结果中取多少条。

示例三:
查询工资最高的5个人, TOP-5

select e.last_name,e.hire_date,e.salary from employees e where rownum<= 5 order by salary desc;
返回:
LAST_NAME                 HIRE_DATE       SALARY
------------------------- ----------- ----------
King                      2003/6/17     24000.00
Kochhar                   2005/9/21     17000.00
Lu                        2022/1/23      1000.00
Lu                        2022/1/23 1    1000.00
Lu                        2022/1/22      1000.00

2. Oracle数据库的分页查询

当查询的结果集数据量过大时,可能会导致各种各样的问题发生,例如:服务器资源被耗尽,因数据传输量过大而使处理超时,等等。最终都会导致查询无法完成。解决这个问题的一个策略就是“分页查询”,也就是说不要一次性查询所有的数据,每次只查询一部分数据。这样分批次地进行处理,可以呈现出很好的用户体验,对服务器资源的消耗也不大。

分页查询原则:

内建视图中通过rownum伪列值的判断来指定获取数据的数量。

示例:

查询雇员表中的数据,每次只返回10条,包含名字,薪水。

-- 前10条
select em.rn, em.last_name,em.salary from (select rownum rn,e.* from employees e) em where em.rn >= 1 and em.rn <= 10;
返回:
        RN LAST_NAME                     SALARY
---------- ------------------------- ----------
         1 Lu                           1000.00
         2 Lu                           1000.00
         ......
        10 Pataballa                    4800.00
10 rows selected
-- 下10条
select em.rn, em.last_name,em.salary from (select rownum rn,e.* from employees e) em where em.rn >= 11 and em.rn <= 20;
返回:
        RN LAST_NAME                     SALARY
---------- ------------------------- ----------
        11 Lorentz                      4200.00
        12 Greenberg                   12008.00
        ......
        20 Baida                        2900.00
10 rows selected

说明:分页查询和Top-N相比,将rownum放入了子查询(内建视图),因为通过rownum可以返回所有列。而Top-N只是为了取前几条或后几条,不能实现取中间的数据。

对于 >= 和 <= ,也可以使用between…and…

-- 当前是第几页  page => 2
-- 每页显示的记录数 size => 5

select *
from (
      select rownum rn, t.*
      from (
           select * from employees order by salary desc
      ) t
      where rownum<=2*5
) tt
where tt.rn>(2-1)*5;
返回:
        RN EMPLOYEE_ID FIRST_NAME           LAST_NAME                 EMAIL                     PHONE_NUMBER         HIRE_DATE   JOB_ID         SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
---------- ----------- -------------------- ------------------------- ------------------------- -------------------- ----------- ---------- ---------- -------------- ---------- -------------
         6         201 Michael              Hartstein                 MHARTSTE                  515.123.5555         2004/2/17   MK_MAN       13000.00                       100            20
         7         108 Nancy                Greenberg                 NGREENBE                  515.124.4569         2002/8/17   FI_MGR       12008.00                       101           100
         8         205 Shelley              Higgins                   SHIGGINS                  515.123.8080         2002/6/7    AC_MGR       12008.00                       101           110
         9         147 Alberto              Errazuriz                 AERRAZUR                  011.44.1344.429278   2005/3/10   SA_MAN       12000.00           0.30        100            80
        10         168 Lisa                 Ozer                      LOZER                     011.44.1343.929268   2005/3/11   SA_REP       11500.00           0.25        148            80

区别:Oracle数据库使用rownum伪列进行分页。Mysql数据库通过 limit(m,n) 的方式进行分页。

关于视图,可以参考以下链接:

https://blog.csdn.net/weixin_45842494/article/details/122675205

你可能感兴趣的:(oracle,数据库,oracle,database)