加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql分页查询几种写法

发布时间:2020-12-12 09:19:10 所属栏目:MsSql教程 来源:网络整理
导读:关于SQL语句分页,网上也有很多,我贴一部分过来,并且总结自己已知的分页到下面,方便日后查阅 1.创建测试环境 ,(插入100万条数据大概耗时5分钟)。 --创建测试表 create table pagetest ( id int identity(1,1) not null,col01 int null,col02 nvarchar(50

关于SQL语句分页,网上也有很多,我贴一部分过来,并且总结自己已知的分页到下面,方便日后查阅

1.创建测试环境

,(插入100万条数据大概耗时5分钟)。

--创建测试表
create table pagetest
(
id int identity(1,1) not null,col01 int null,col02 nvarchar(50) null,col03 datetime null
)

--1万记录集
declare @i int
set @i=0
while(@i<10000)
begin
insert into pagetest select cast(floor(rand()*10000) as int),left(newid(),10),getdate()
set @i=@i+1
end

2.几种典型的分页sql

下面例子是每页50条,198*50=9900,取第199页数据。

--写法1,not in/top

--写法2,not exists


--写法3,max/top


(select max(id) from (select top 9900 id from pagetest order by id)a) order by id

--写法4,row_number()


9900

select from
(select row_number()over(order by id)rownumber,
from pagetest)a
where rownumber>9900 and rownumber<9951

select from
(select row_number()over(order by id)rownumber,
from pagetest)a
where rownumber between 9901 and 9950

--写法5,在csdn上一帖子看到的,row_number() 变体,不基于已有字段产生记录序号,先按条件筛选以及排好序,再在结果集上给一常量列用于产生记录序号

9900

3.分别在1万,10万(取1990页),100(取19900页)记录集下测试。

测试sql:

select @end_date = getdate() select datediff(ms,@begin_date,@end_date) as '毫秒'

1万:基本感觉不到差异。

10万:

4.结论:

PS.上面的分页排序都是基于自增字段id。测试环境还提供了int,nvarchar,datetime类型字段,也可以试试。不过对于非主键没索引的大数据量排序效率应该是很不理想的。

5.简单将ROWNUMBER,max/top的方式封装到存储过程。

ALTER PROCEDURE [dbo].[Proc_SqlPageByRownumber]
(
@tbName VARCHAR(255),--表名
@tbGetFields VARCHAR(1000)= '*',--返回字段
@OrderfldName VARCHAR(255),--排序的字段名
@PageSize INT=20,--页尺寸
@PageIndex INT=1,--页码
@OrderType bit = 0,--0升序,非0降序
@strWhere VARCHAR(1000)='',--查询条件
--@TotalCount INT OUTPUT --返回总记录数
)
AS
-- =============================================
-- Author: allen (liyuxin)
-- Create date: 2012-03-30
-- Description: 分页存储过程(支持多表连接查询)
-- Modify [1]: 2012-03-30
-- =============================================
BEGIN
DECLARE @strSql VARCHAR(5000) --主语句
DECLARE @strSqlCount NVARCHAR(500)--查询记录总数主语句
DECLARE @strOrder VARCHAR(300) -- 排序类型

--------------总记录数---------------
IF ISNULL(@strWhere,'') <>''
SET @strSqlCount='Select @TotalCout=count() from ' + @tbName + ' where 1=1 '+ @strWhere
ELSE SET @strSqlCount='Select @TotalCout=count(
) from ' + @tbName

--exec sp_executesql @strSqlCount,N'@TotalCout int output',@TotalCount output
--------------分页------------
IF @PageIndex <= 0 SET @PageIndex = 1

IF(@OrderType<>0) SET @strOrder=' ORDER BY '+@OrderfldName+' DESC '
ELSE SET @strOrder=' ORDER BY '+@OrderfldName+' ASC '

SET @strSql='SELECT FROM
(SELECT ROW_NUMBER() OVER('+@strOrder+') RowNo,'+ @tbGetFields+' FROM ' + @tbName + ' WHERE 1=1 ' + @strWhere+' ) tb
WHERE tb.RowNo BETWEEN '+str((@PageIndex-1)
@PageSize+1)+' AND ' +str(@PageIndex*@PageSize)

exec(@strSql)
SELECT @TotalCount
END

<div class="jb51code">
<pre class="brush:sql;">
public static SqlParameter MakeInParam(string ParamName,SqlDbType DbType,Int32 Size,object Value)
{
return MakeParam(ParamName,DbType,Size,ParameterDirection.Input,Value);
}
public static SqlParameter MakeOutParam(string ParamName,SqlDbType DbType)
{
return MakeParam(ParamName,ParameterDirection.Output,null);
}
public static SqlParameter MakeParam(string ParamName,ParameterDirection Direction,object Value)
{
SqlParameter param;
if (Size > 0)
param = new SqlParameter(ParamName,Size);
else
param = new SqlParameter(ParamName,DbType);
param.Direction = Direction;
if (!(Direction == ParameterDirection.Output && Value == null))
param.Value = Value;
return param;
}
///


/// 分页获取数据列表及总行数
///

/// <param name="tbName">表名
/// <param name="tbGetFields">返回字段
/// <param name="OrderFldName">排序的字段名
/// <param name="PageSize">页尺寸
/// <param name="PageIndex">页码
/// <param name="OrderType">false升序,true降序
/// <param name="strWhere">查询条件
public static DataSet GetPageList(string tbName,string tbGetFields,string OrderFldName,int PageSize,int PageIndex,string strWhere)
{
SqlParameter[] parameters = {
MakeInParam("@tbName",SqlDbType.VarChar,255,tbName),MakeInParam("@tbGetFields",1000,tbGetFields),MakeInParam("@OrderfldName",OrderFldName),MakeInParam("@PageSize",SqlDbType.Int,PageSize),MakeInParam("@PageIndex",PageIndex),MakeInParam("@OrderType",SqlDbType.Bit,OrderType),MakeInParam("@strWhere",strWhere),// MakeOutParam("@TotalCount",SqlDbType.Int)
};
return RunProcedure("Proc_SqlPageByRownumber",parameters,"ds");
}

调用:


1.必填项:tbName,OrderfldName,tbGetFields


2.实例:


Max/top:(简单写了下,需要满足主键字段名称就是"id")

--------------总记录数---------------
if @strWhere !=''
begin
set @strSqlCount='Select @TotalCout=count() from ' + @tbName + ' where '+ @strWhere
end
else
begin
set @strSqlCount='Select @TotalCout=count(
) from ' + @tbName
end
--------------分页------------
if @PageIndex <= 0
begin
set @PageIndex = 1
end

set @strSql='select top '+str(@PageSize)+' from ' + @tbName + '
where id>(select max(id) from (select top '+str((@PageIndex-1)
@PageSize)+' id from ' + @tbName + ''+@strOrder+')a)
'+@strOrder+''

exec sp_executesql @strSqlCount,@Total output
exec(@strSql)

园子里搜到Max/top这么一个版本,看起来很强大,

调用:

以上就是本文针对sql分页查询几种写法的全部内容,希望大家喜欢。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读