目录
一、使用ROWNUM
1.基本概念
2.使用规则与限制
3.常见应用场景
二、使用OFFSET和FETCH
1.基本概念
2.使用方法
三、使用ROW_NUMBER()窗口函数
1.基本语法
2.功能特点
3.使用场景
4.示例
引言
Oracle数据库的分页处理是数据库处理中常见的操作,尤其在需要展示大量数据的情况下,合理的分页不仅能提升用户体验,还能提高查询效率。
Oracle分页总结有三种方法:使用ROWNUM,使用OFFSET和FETCH,使用ROW_NUMBER()窗口函数。下面我将逐一举例子详细介绍。
一、使用ROWNUM
1.基本概念
介绍:ROWNUM是Oracle数据库中的一个伪列,它用于为查询结果中的每一行分配一个唯一的数字标识。
定义:ROWNUM是Oracle特有的一个伪列,它并不存在于数据库的表中,而是在查询结果返回时由Oracle数据库动态生成,是Oracle数据库为了方便查询而自动添加的一个列。。
作用:为查询结果集中的每一行分配给一个唯一的序号,从一开始依次递增。
2.使用规则与限制
生成时机:ROWNUM是在查询结果集返回给客户端之前生成的,它并不按照表中数据的物理顺序或者特定的列值顺序来生成的。
使用限制:ROWNUM通常只能用于小于或者小于等于的比较操作中。直接用大于或者大于等于的比较操作可能会导致查询结果为空集。
子查询使用:由于ROWNUM的上述限制,当需要基于ROWNUM进行大于某个值的筛选时,通常需要通过子查询来实现。即先在一个子查询中生成ROWNUM,然后在外层查询中基于这个ROWNUM进行筛选。
3.常见应用场景
1.限制返回行数
使用它来限制查询结果返回的行数。
select * from staudent where ROWNUM <=5; --返回学生表中前五行的数据。
2.分页查询
虽然ROWNUM本身不能实现直接的分页查询(跳过前N行,返回接下来的M行),但可以通过结合子查询和排序操作来实现分页效果。
select *
from(select s.* ,ROWNUM rnum
from (select *
from student order by s_id desc
) s where ROWNUM <=10
) where rnum > 5;
通用分页查询模版
SELECT *
FROM (
SELECT e.*, ROWNUM rnum
FROM (
SELECT *
FROM your_table
ORDER BY your_sort_column asc|desc
) e
WHERE ROWNUM <= :endRow
)
WHERE rnum > :startRow;
your_table 是你要查询的表名。your_sort_column 是你用来排序的列。:startRow 是你希望跳过的行数(基于1的索引)。:endRow 是你希望返回的总行数(包括跳过的行数)。
二、使用OFFSET和FETCH
在Oracle数据库中,OFFSET和FETCH是用于分页查询的关键字,它们从Oracle 12c版本开始被引入,提供了一种更加直观和高效的方式来实现分页功能。
1.基本概念
OFFSET:表示从结果集中跳过的行数。 它是一个非负数,用于指定从哪一行开始返回数据。
FETCH:表示从结果集中返回的行数。它也是一个非负数,用于指定要返回的行数。
2.使用方法
虽然order by 字句不是使用OFFSET和FETCH的必需条件,但是建议在使用分页查询时指定排序列。
假设有一个名为employees的表,包含以下列:employee_id, first_name, last_name, salary。我们希望查询第2页的数据,每页显示5条记录。示例:
SELECT employee_id, first_name, last_name, salary
FROM employees
ORDER BY employee_id DESC
OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY;
通用分页的基本语法如下:
select column1,column2,...
from table_name
Order by column_name desc|asc
OFFSET offset_value ROWS FETCH NEXT fetch_value ROWS Only;
column1, column2, ... 是要查询的列名。table_name 是要查询的表名。column_name 是用于排序的列名。注意,虽然ORDER BY子句不是必须的,但通常建议使用,以确保分页结果的有序性。offset_value 是要跳过的行数。fetch_value 是要返回的行数。
三、使用ROW_NUMBER()窗口函数
ROW_NUMBER()是Oracle数据库中的一个窗口函数,用于为查询结果集中的每一行分配给一个连续整数值。
1.基本语法
ROW_NUMBER() OVER ([PARTITION BY column] ORDER BY column [ASC|DESC])
PARTITION BY column:可选参数。用于将结果集分为多个分区(组),每个分区内部单独排序和编号。如果不指定此参数,则整个结果集被视为一个单一分区。ORDER BY column [ASC|DESC]:必需参数。用于指定分配行号时的排序顺序。ASC表示升序,DESC表示降序。
2.功能特点
唯一性:ROW_NUMBER()函数确保为每一行分配一个唯一的行号,即使在分区内也是如此。
连续性:行号是连续的整数,从1开始递增。
基于排序:行号的分配是基于指定的排序顺序的。因此,在查询中使用ROW_NUMBER()时,通常需要指定ORDER BY子句。
3.使用场景
分页查询:可以结合子查询和排序操作来实现分页效果。
数据去重:与PARITION BY 结合使用,可以为每个分区的重复数据分配序号,然后只选择序号为一的行来实现去重。
排名问题:可以为每个部门或产品类别生成一个排名列表。
4.示例
基本用法
假设我们有一个名为 Employees 的表,其中包含员工的 ID、姓名和部门。我们想要为每个部门的员工按姓名排序并分配一个行号。
SELECT
Department,
Name,
ROW_NUMBER() OVER (PARTITION BY Department ORDER BY Name ASC) AS RowNum
FROM
Employees;
运行结果
Department | Name | RowNum
------------|------------|-------
Sales | Alice | 1
Sales | Bob | 2
Sales | Charlie | 3
Marketing | Dave | 1
Marketing | Eva | 2
Marketing | Frank | 3
IT | Grace | 1
IT | Henry | 2
分页查询
获取员工表中薪资排名第四到第六的员工信息:
SELECT *
FROM (
SELECT id,name,salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn
FROM employees
)
WHERE rn BETWEEN 4 AND 6;
数据去重
获取每个部门薪资最高的员工:
SELECT *
FROM (
SELECT id, name,salary,
ROW_NUMMBER() OVER (PARTITION BY department_id ORDER BY salary DESC)
FROM employees
)
where rn = 1;