行号分页

9/1/2015来源:SQL技巧人气:1394

行号分页

上一篇的博客是子查询分页,在数据量大的情况下,分页的效率是非常低。今天来讲一下行号分页,这个是用的比较多的。

数据库还是用Northwind数据库。就用Orders表为例子吧,假设每页都显示10条记录。

我们先查询第一页的数据。

SELECT  *FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY OrderID ) AS RowNumber ,                    *          FROM      Orders        ) TWHERE   RowNumber BETWEEN 1 AND 10

这里用到一个函数ROW_NUMBER() OVER函数,这个函数的语法是ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)

简单的说ROW_NUMBER()从1开始,为每一条分组记录返回一个数字,这里的ROW_NUMBER() OVER (ORDER BY OrderID) 是先把OrderID列升序,再为升序以后的每条记录返回一个序号。

接下来,查询第二页的数据。

SELECT  *FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY OrderID ) AS RowNumber ,                    *          FROM      Orders        ) TWHERE   RowNumber BETWEEN 11 AND 20

由此可以推断出,第N页的数据为

SELECT  *FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY OrderID ) AS RowNumber ,                    *          FROM      Orders        ) TWHERE   RowNumber BETWEEN (N-1)*10+1 AND N*10

写成通用的SQL语句如下:

BEGIN    DECLARE @PageSize INT     --每页显示条数    DECLARE @PageIndex INT    --页码(从1开始)    SET @PageSize = 10    SET @PageIndex = 2    SELECT  *    FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY OrderID ) AS RowNumber ,                        *              FROM      Orders            ) T    WHERE   RowNumber BETWEEN ( ( @PageIndex - 1 ) * @PageSize + 1 )                      AND     ( @PageIndex * @PageSize )    ORDER BY OrderID ASCEND

写成存储过程如下:

--存储过程CREATE PROCEDURE P_GetPagedOrders2    @PageSize INT ,             --每页显示条数    @PageIndex INT ,            --页码(从1开始)    @RecordCount INT OUTPUT ,    --数据总数    @PageCount INT OUTPUT        --总页数AS    BEGIN        --获取数据总数        SELECT  @RecordCount = COUNT(1)        FROM    dbo.Orders        --计算总页数        SET @PageCount = @RecordCount / @PageSize        IF @RecordCount % @PageSize > 0            BEGIN                SET @PageCount = @PageCount + 1            END        --获取当前页的数据        SELECT  *        FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY OrderID ) AS RowNumber ,                            *                  FROM      Orders                ) T        WHERE   RowNumber BETWEEN ( ( @PageIndex - 1 ) * @PageSize + 1 )                          AND     ( @PageIndex * @PageSize )        ORDER BY OrderID ASC    END

测试存储过程

DECLARE    @RecordCount int,           @PageCount intEXEC    [P_GetPagedOrders2]        @PageSize = 10,        @PageIndex = 2,        @RecordCount = @RecordCount OUTPUT,        @PageCount = @PageCount OUTPUTSELECT    @RecordCount as N'@RecordCount',        @PageCount as N'@PageCount'

测试结果如下

不足之处,还望各位大神指正,不胜感激。