Top-N查询需要基于一个条件,从表中显示最前面的n条记录或最后面的n条记录时是有用的。该结果可以用于进一步分析,例如,用Top-N 分析你可以执行下面的查询类型:
说得简单一点就是排名。
Top-N查询使用一个带有下面描述的元素的一致的嵌套查询结构:
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
当查询的结果集数据量过大时,可能会导致各种各样的问题发生,例如:服务器资源被耗尽,因数据传输量过大而使处理超时,等等。最终都会导致查询无法完成。解决这个问题的一个策略就是“分页查询”,也就是说不要一次性查询所有的数据,每次只查询一部分数据。这样分批次地进行处理,可以呈现出很好的用户体验,对服务器资源的消耗也不大。
分页查询原则:
在内建视图中通过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