最近项目中需要在SQL SERVER中进行分页,需要编写分页查询语句。之前也写过一些关于分页查询的语句,但是性能不敢恭维。于是在业务时间,在微软社区Bing了一篇老外写的关于SQL SERVER分页的文章。看过之后,感觉自己之前写的语句,太低端,太不科学了。  文章中讲了两种分页方法,其中一种只适用于SQL SERVER2012以上版本。

ROW_NUMBER()函数分页

先介绍一下ROW_NUMBER()函数,这个函数的主要作用,从它的命名中就可看出来。ROW,每列,NUMBER数字,它的作用就是为每行分配一个数字。但是它一般不单独使用。它的语法是这样的:

PARTITION BY value_expression: 这个参数是通过value_expression,把我们查询到结果集给分成若干区。举个例子,我们有一张成绩表。我们要为女生、男生在各自性别内按成绩排名次。这时,我们就可以通过PARTITTION BY GENDER(性别字段) 将全班人员分为两个区,女生区、男生区。男生在男生区排名次,女生在女生区排名次。

order_by_clause:这个是就是order by 语句,将数据集按某个字段进行排序。

需要注意的是,PARTITION BY value_expression不是必要参数,但是order_by_clause是必要参数。要使用ROW_NUMBER()必须要有order by 语句。下面给出几个ROW_NUMBER() 实际使用场景:

1.

这个语句把表中TerritoryName不为空、SalesYID不为空的数据按字段SalesYTD降序排序,再通过ROW_NUMBER()函数为每行分配一个连续的数字,将数字存入新添加的一个名为Row的字段中。结果如下:

2.这种情况,就是我们今天要讲的分页方法。(Returning a subset of rows)

在这个场景中,我们用到了Comoon table  expression(中间表表达式),它的作用与临时表差不多。就是将查询到的结果放入一个地方,供再次查询。对Common Table Expression感兴趣的可以去MSDN上学习。原文地址:http://msdn.microsoft.com/en-us/library/ms175972.aspx.

我们使用ROW_NUMBER()函数为查询的结果每行数据分配一个数字,将数字放入RowNumber列中(通过AS 生成的新列)。再将数据集放入中间表OrderedOrders中。查询中间表,这个时候我们就可以使用Where RowNumber BETWEEN A AND B.来读取从A条到B条的数据了,就可以达到我们的分页需求了.

3.Using ROW_NUMBER() with PARTITION

在这个场景中,我们用到了PARTITION参数。我们按区域(territoryName)将查询结果进行分区,再在分过区的数据集中以SalesYTD降序,再为降序后的每行数据分配数字。最后以TerritoryName字段升序。结果如下图:

关于ROW_NUMBER()的原文地址:http://msdn.microsoft.com/en-us/library/ms186734.aspx.

这种分页方法的主要思想,就是通过ROW_NUMBER()为每行生成标识。再通过BETWEEN  AND 语句来获取当前页的数据,已达到分页的作用。

我们创建了一个表名TB.EXMPLE的表,添加了1,000,000条数据。我们通过这种分页方法来编写如下查询语句:

-----查看每页显示10条,第2页的数据
DECLARE @PageNumber AS INT,@RowNumber AS INT
SET @PageNumber=2
SET @RowNumber=5 SELETCT * FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ID_EXMPLE) AS NUMBER,
* FROM TB_EXAMPLE
)AS TBL WHERE NUMBER BETWEEN ((@PageNumber-1)*@RowNumber+1) AND (@PageNumber*@RowNumber)

结果如下:

2.OFFSET  AND FETCH 分页

offset and fetch,这是SQL SERVER 2012新添加的功能。2012以下版本,不支持。

DECALER @PageNumber AS INT,@RowNumber AS INT
SET @PageNumber=2
SET @RowNumber=5 SELECT * FROM TB_EXAMPLE
WHERE OFFSET ((@PageNumber-1)*@RowNumber) ROWS
FETCH NEXT @RowNumber ROWS ONLY;

OFFSET   A ROWS ,将前A条记录舍去,FETCH NEXT B ROWS ,向后在读取B条数据。

原文地址如下:http://social.technet.microsoft.com/wiki/contents/articles/23811.paging-a-query-with-sql-server.aspx.

SQL SERVER 分页方法的更多相关文章

  1. SQL Server游标 C# DataTable.Select() 筛选数据 什么是SQL游标? SQL Server数据类型转换方法 LinQ是什么? SQL Server 分页方法汇总

    SQL Server游标   转载自:http://www.cnblogs.com/knowledgesea/p/3699851.html. 什么是游标 结果集,结果集就是select查询之后返回的所 ...

  2. SQL Server 分页方法汇总

    PageSize = 30 PageNumber = 201 方法一:(最常用的分页代码, top / not in) UserId UserId from UserInfo order by Use ...

  3. SQL server 分页方法小结

    这里面介绍一下常用的分页方法: 1.使用top来分页 select top @pageSize * from table where id not in (select top @pageSize*( ...

  4. SQL server分页的四种方法

    SQL server分页的四种方法 1.三重循环: 2.利用max(主键); 3.利用row_number关键字: 4.offset/fetch next关键字 方法一:三重循环思路  先取前20页, ...

  5. SQL server分页的四种方法(算很全面了)

      这篇博客讲的是SQL server的分页方法,用的SQL server 2012版本.下面都用pageIndex表示页数,pageSize表示一页包含的记录.并且下面涉及到具体例子的,设定查询第2 ...

  6. 解决hibernate对Sql Server分页慢的问题

    一.hibernate分页 hibernate对MsSql的伪分页 分页是web项目中比不可少的一个功能,数据量大的时候不能全部展示必然要用到分页技术.相信大家对hibernate中的分页都不陌生: ...

  7. 干货 | SSMS客户端连接京东云RDS SQL Server配置方法

    干货 | SSMS客户端连接京东云RDS SQL Server配置方法 原创: 于振江 京东云开发者社区  微软SQL Server, Oracle数据库以及MySQL系列占据了关系型数据库市场的绝对 ...

  8. SQL Server分页模板

    SQL Server分页模板 WITH T AS ( SELECT ROW_NUMBER() OVER(ORDER BY AlbumId ) AS row_number, * FROM (SELECT ...

  9. SQL Server分页语句ROW_NUMBER,读取第4页数据,每页10条

    SQL Server分页语句ROW_NUMBER,读取第4页数据,每页10条 SELECT Id,[Title],[Content],[Image] FROM ( SELECT ROW_NUMBER( ...

随机推荐

  1. 总结一下apply和call的异同点

    call, apply都属于Function.prototype的一个方法,它是JavaScript引擎内在实现的,因为属于Function.prototype,所以每个Function对象实例,也就 ...

  2. JavaScript中的內定物件與函式: arguments, callee, caller, this, apply(), call()

    arguments, caller, callee, this都是用在函式(function)內的特殊內定物件.而apply()及call()則是用來呼叫函式的不同作法. arguments可用來取得 ...

  3. json格式初涉

    json用{}表示json对象,[]表示数组,里面以值对的方式来存储信息 var jsondata='{"staff": [{"name":"jim& ...

  4. PHP学习系列(1)——字符串处理函数(4)

    16.hebrevc() 函数把希伯来文本从右至左的流转换为左至右的流.它也会把新行 (\n) 转换为 <br />.只有 224 至 251 之间的 ASCII 字符,以及标点符号受到影 ...

  5. twisted(2)--聊天系统

    我们今天要做一个聊天系统,这样可以和我们之前flask api那系列文章结合起来:其次,聊天系统最能代表tcpserver,以后可以套用各种模型,比如我们公司做的物联网,其实就是把聊天系统简化一下. ...

  6. T-SQL事务实例

    begin try begin tran ,'); ; --RAISERROR ('Error raised in TRY block.',16,1); commit tran end try beg ...

  7. Android判读是否安装了某一款APP

    /** * @Title: isAvilible * @Description: 断手机已安装某程序 * @param @param context * @param @param packageNa ...

  8. [转]Android读写文件

    一.       从resource中的raw文件夹中获取文件并读取数据(资源文件只能读不能写) String res = ""; try{ InputStream in = ge ...

  9. ural 1723 Sandro's Book

    http://acm.timus.ru/problem.aspx?space=1&num=1723 #include <cstdio> #include <cstring&g ...

  10. 【转】随身HiFi 安卓OTG功能在音频上的妙用

    原文网址:http://article.pchome.net/content-1745467.html 随身HiFi 安卓OTG功能在音频上的妙用 [PChome电脑之家音频频道原创]说起Androi ...