分享几种个人常用的sql server分页的方法
1. ROW_NUMBER() OVER()和BETWEEN
2. OFFSET FETCH NEXT
3. 基于存储过程
准备测试数据
if exists(select 'x' from sys.tables where name='userInfo')
drop table userInfo
go
create table userInfo(
Id int primary key identity(1001,1),
userName varchar(20) not null
)
go
insert into userInfo values('刘一'),
('陈二'),
('张三'),
('李四'),
('王五'),
('赵六'),
('孙七'),
('周八'),
('吴九'),
('郑十');
- 第一种基于ROW_NUMBER() OVER()和between–通用型
--between:选取介于两个值之间的数据范围
/*ROW_NUMBER():返回结果集分区内行的序列号,每个分区的第一行从1开始
配合 over()使用 over(ORDER BY ID):指定排序方式
注:如直接使用ID,不能排除ID跳号的情况*/
select Id,userName
from (select *,ROW_NUMBER() over(order by id) ROW_ID from userInfo) t
where t.ROW_ID between (5*(1-1)+1) and 5*1
思路:基于between达到选取每页需要的数据。
公式:(每页条数*(当前页数-1)+1) and 每页条数*当前页数 结果:就是1 and 5,例子是我每页只分五条数据。每点击下一页把当前页数+1就完成了分页效果。
如需要带上总页数:
/*ceiling():向上取整,如除数是整数,要*1.0转成小数才效果最佳.
注意:取整时需注意正负数小数位四舍五入问题*/
select id,userName,ceiling(1.0*t.pageCounts/5) as 总页数
from (select *,ROW_NUMBER() over(order by id) ROW_ID, COUNT(0) OVER() AS pageCounts from userInfo) t
where t.ROW_ID between (5*(1-1)+1) and 5*1
- 第二种基于OFFSET FETCH NEXT方式–推荐型
此方法需要在SQL server 2012及更高版本支持,如果自己的版本支持那么推荐使用此方法,相对于ROW_NUMBER() OVER()和between的性能有较大提升。
使用注意事项:ORDER BY 是使用 OFFSET 和 FETCH 子句所必需的
OFFSET :用于指定跳过(Skip)的数据行
Fetch:该子句在Offset子句之后执行,表示在跳过(Sikp)指定数量的数据行之后,返回一定数据量的数据行
执行顺序:Offset子句必须在Order By 子句之后执行,Fetch子句必须在Offset子句之后执行
TOP 不能在同一个查询表达式中与 OFFSET 和 FETCH 一起使用
select * from userInfo order by id OFFSET (5*(1-1)) rows fetch next 5 rows only
思路:使用OFFSET 跳过开始行数,然后使用FETCH NEXT返回结束行数的剩余数
公式:OFFSET 开始行数 ROWS FETCH NEXT 结束行数 ROWS ONLY
结果:跳过第0行从第1行开始,返回从第1行开始往下数的五行数据,假如是第二页(5*(2-1)),就是跳过第五行开始,返回从第6行开始往下数的五行数据
- 第三种基于存储过程–实际上也是通过第二种方法实现
注意事项与第二种基本同步
if exists(select 'x' from sys.objects where name='SP_Page')
drop proc SP_Page
go
CREATE procedure SP_Page
@tablename varchar(20), --表名
@pageSize int, --每页条数
@page int --页数
AS
declare @newspage int,
@res varchar(100)
begin
set @newspage=@pageSize*(@page - 1)
set @res='select * from ' +@tablename+ ' order by ID offset '+CAST(@newspage as varchar(10)) +' rows fetch next '+ CAST(@pageSize as varchar(10)) +' rows only'
exec(@res)
end
go
--调用存储过程
EXEC SP_Page @tablename='userInfo',@pageSize=5,@page=1
注:我们总是喜欢拿顺其自然来敷衍人生道路上的荆棘坎坷,却很少承认真正的顺其自然,其实是竭尽所能之后的不强求而非两手一摊的不作为
希望对你有所帮助