MySQL的分页实现是使用LIMIT关键字。
Oracle的分页是实现主要是基于rownum行号。
SQL Server的分页主要使用的关键字是TOP。
具体用法总结如下:
1,分页一般有两个参数,当前页 pageIndex,每页数量 pageSize。
2,实例中查询表名EMP,主键为ID,查询每页数量100条。数据表中共10W条记录。
LIMIT子句可以被用于限制被SELECT语句返回的行数。
使用两个参数时,第一个参数指定返回的偏移量,第二个参数指定返回的行数。初始行的偏移量为0(不是1):
mysql> SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
使用一个参数时,指定从开头返回的行数:
mysql> SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows
-- 分页查询 通用语句
SELECT * FROM TABLE
LIMIT (pageIndex-1)*pageSize,pageSize
-- 第一页 每页100条
SELECT * FROM EMP LIMIT 0,100
-- 第二页 每页100条
SELECT * FROM EMP LIMIT 100,100
-- 第801页 每页100条
SELECT * FROM EMP LIMIT 80000,100 -- 用时0.046s
rownum 是伪列,数据库自己创建出来的字段。为每个查询的结果集从1开始生成序号。
rownum不支持>, >=, =, between and,只支持<, <=等。
查询时使用rownum <= 5 返回5条数据,rownum <=10 and rownum >=6 返回0条数据。
为了实现分页,一般使用子查询使rownum成为子查询结果集的具体列。
-- 分页查询 通用语句
SELECT * FROM
( SELECT ROWNUM AS MYROWNUM, t1.* FROM TABLE t1 ORDER BY ID ) t2
WHERE MYROWNUM > ( pageIndex - 1 ) * pageSize
AND MYROWNUM <= pageIndex * pageSize
-- 第一页 每页100条
SELECT * FROM
( SELECT ROWNUM AS RN, E.* FROM EMP E ORDER BY ID ) T
WHERE RN > 0 AND RN <= 100 -- 用时0.023s
-- 第二页 每页100条
SELECT * FROM
( SELECT ROWNUM AS RN, E.* FROM EMP E ORDER BY ID ) T
WHERE RN > 100 AND RN <= 200 -- 用时0.026s
-- 第801页 每页100条
SELECT * FROM
( SELECT ROWNUM AS RN, E.* FROM EMP E ORDER BY ID ) T
WHERE RN > 800100 AND RN <= 800200 -- 用时0.046s
[ OFFSET offset ROWS]
FETCH NEXT [ row_count | percent PERCENT ] ROWS [ ONLY | WITH TIES ]
1,OFFSET 子句指定在行限制开始之前要跳过行数
2,FETCH 子句指定要返回的行数或百分比
3,简单理解为:offset A rows ,将前A条记录舍去,fetch next B rows only ,向后在读取B条数据
-- 分页查询 通用语句
SELECT * FROM TABLE
OFFSET ( pageIndex - 1 ) * pageSize ROWS
FETCH NEXT pageIndex * pageSize ROWS ONLY
-- 第一页 每页100条
SELECT * FROM EMP ORDER BY ID OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY
-- 第二页 每页100条
SELECT * FROM EMP ORDER BY ID OFFSET 100 ROWS FETCH NEXT 200 ROWS ONLY -- 用时0.016s
-- 第801页 每页100条
SELECT * FROM EMP ORDER BY ID OFFSET 80000 ROWS FETCH NEXT 80100 ROWS ONLY --用时0.135s
TOP 将在查询结果集中返回的行数限制到指定行数
-- 分页查询 通用语句
SELECT TOP pageSize * FROM TABLE
WHERE ID NOT IN (
SELECT TOP (pageIndex-1)*pageSize ID FROM TABLE
)
-- 第一页 每页100条
select top 100 * from EMP --where id not in (select top 0 id from emp )
-- 第二页 每页100条
select top 100 * from EMP where id not in (select top 100 id from emp )
-- 第801页 每页100条
select top 100 * from EMP where id not in (select top 80000 id from emp )
row_number() over(order by id)
函数计算出行数,利用子查询即可实现,可结合top使用。
写法实现:
-- 分页查询 通用语句
SELECT TOP pageSize * FROM
(select row_number() over(order by id ) AS myrownumber,* from TABLE) t
WHERE myrownumber > (pageIndex-1)*pageSize
--或者使用 <=
SELECT * FROM
(select row_number() over(order by id ) AS myrownumber,* from TABLE) t
WHERE myrownumber > (pageIndex-1)*pageSize and myrownumber <= pageIndex*pageSize
-- 第一页 每页100条
select top 100 * from EMP
select TEMP.* from (select row_number() over(order by id ) AS rownumber,* from EMP) TEMP where rownumber >0 and rownumber <=100
-- 第801页 每页100条
select top 100 TEMP.* from (select row_number() over(order by id ) AS rownumber,* from EMP) TEMP where rownumber >80000
select TEMP.* from (select row_number() over(order by id ) AS rownumber,* from EMP) TEMP where rownumber >80000 and rownumber <=80100
适用于:SQL Server 2012 (11.x) 及更高版本和 Azure SQL 数据库。
-- Syntax for SQL Server and Azure SQL Database
ORDER BY order_by_expression
[ COLLATE collation_name ]
[ ASC | DESC ]
[ ,...n ]
[ ]
::=
{
OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS }
[
FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW | ROWS } ONLY
]
}
1,OFFSET 指定开始从查询表达式返回行之前跳过的行数。 该值可以是大于或等于零的整数常量或表达式
2,FETCH 指定在处理 OFFSET 子句后返回的行数。 该值可以是大于或等于 1 的整数常量或表达式。
3,要有ORDER BY 没有ORDER BY无法查询到结果
-- 分页查询 通用语句
SELECT * FROM TABLE
ORDER BY ID
OFFSET ( pageIndex - 1 ) * pageSize ROWS
FETCH NEXT pageIndex * pageSize ROWS ONLY
-- 第一页 每页100条
SELECT * FROM EMP ORDER BY ID OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY
-- 第二页 每页100条
SELECT * FROM EMP ORDER BY ID OFFSET 100 ROWS FETCH NEXT 200 ROWS ONLY
-- 第801页 每页100条
SELECT * FROM EMP ORDER BY ID OFFSET 80000 ROWS FETCH NEXT 80100 ROWS ONLY
SQL Sever限制行数推荐使用TOP(或 OFFSET 和 FETCH):
使用 TOP(或 OFFSET 和 FETCH)而非 SET ROWCOUNT 限制返回的行数。 这些方法之所以优于使用 SET ROWCOUNT,原因包括以下各项:
- 作为 SELECT 语句的一部分,查询优化器在查询优化期间可能会考虑 TOP 或 FETCH 子句中 expression 的值。 由于在运行查询的语句外部使用 SET ROWCOUNT,不会在查询计划中考虑它的值。