排序分页

Posted Wendy.Jacky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序分页相关的知识,希望对你有一定的参考价值。

继续上一篇的行号分页,接下来讲讲排序分页。

数据库依旧是Northwind,表依旧是Orders,假设每页显示10条记录。

我们先查询第一页的记录。

SELECT TOP 10
        *
FROM    dbo.Orders
ORDER BY OrderID ASC

第二页的记录,先升序取出前20条记录,然后在这20条记录里倒序取出前10条记录,最后把这10条记录升序一下。

SELECT  *
FROM    ( SELECT TOP 10
                    *
          FROM      ( SELECT TOP 20
                                *
                      FROM      dbo.Orders
                      ORDER BY  OrderID ASC
                    ) T
          ORDER BY  T.OrderID DESC
        ) T2
ORDER BY T2.OrderID ASC

第三页的记录,先升序取出前30条记录,然后在这30条记录里倒序取出前10条记录,最后把这10条记录升序一下。

SELECT  *
FROM    ( SELECT TOP 10
                    *
          FROM      ( SELECT TOP 30
                                *
                      FROM      dbo.Orders
                      ORDER BY  OrderID ASC
                    ) T
          ORDER BY  T.OrderID DESC
        ) T2
ORDER BY T2.OrderID ASC

由此可以推断出,第N页记录为:

SELECT  *
FROM    ( SELECT TOP 10
                    *
          FROM      ( SELECT TOP N * 10
                                *
                      FROM      dbo.Orders
                      ORDER BY  OrderID ASC
                    ) T
          ORDER BY  T.OrderID DESC
        ) T2
ORDER BY T2.OrderID ASC

写成通用的SQL语句如下:

BEGIN
    DECLARE @PageSize INT     --每页显示条数
    DECLARE @PageIndex INT    --页码(从1开始)
    SET @PageSize = 10
    SET @PageIndex = 1
    SELECT  *
    FROM    ( SELECT TOP ( @PageSize )
                        *
              FROM      ( SELECT TOP ( @PageIndex * @PageSize )
                                    *
                          FROM      dbo.Orders
                          ORDER BY  OrderID ASC
                        ) T
              ORDER BY  T.OrderID DESC
            ) T2
    ORDER BY T2.OrderID ASC
END

 写成存储过程如下:

CREATE PROCEDURE P_GetPagedOrders3
    @PageSize INT ,              -- 每页显示条数
    @PageIndex INT ,             -- 页码(从1开始)
    @RecordCount INT OUTPUT ,    -- 数据总数
    @PageCount INT OUTPUT        -- 总页数
AS
    BEGIN
    -- 获取数据总数
        SELECT  @RecordCount = COUNT(1)
        FROM    dbo.Orders
        -- 计算总页数
        SET @PageCount = ( @RecordCount + @PageSize - 1 ) / @PageSize
        -- 获取当前页的数据
        IF @PageIndex < @PageCount -- 不是最后一页
            BEGIN
                SELECT  *
                FROM    ( SELECT TOP ( @PageSize )
                                    *
                          FROM      ( SELECT TOP ( @PageIndex * @PageSize )
                                                *
                                      FROM      dbo.Orders
                                      ORDER BY  OrderID ASC
                                    ) T
                          ORDER BY  T.OrderID DESC
                        ) T2
                ORDER BY T2.OrderID ASC
            END
        ELSE -- 最后一页
            BEGIN
                SELECT  *
                FROM    ( SELECT TOP ( @RecordCount % @PageSize )
                                    *
                          FROM      dbo.Orders
                          ORDER BY  OrderID ASC
                        ) T
                ORDER BY T.OrderID ASC
            END
    END

注意,最后一页需要特殊处理。

测试存储过程:

DECLARE    @RecordCount int,
        @PageCount int

EXEC    [dbo].[P_GetPagedOrders3]
        @PageSize = 10,
        @PageIndex = 2,
        @RecordCount = @RecordCount OUTPUT,
        @PageCount = @PageCount OUTPUT

SELECT    @RecordCount as N\'@RecordCount\',
        @PageCount as N\'@PageCount\'

测试结果如下:

 

以上是关于排序分页的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 分页 数据丢失问题解决

modx - 当我在同上片段中使用“&documents =”参数时,分页不起作用

片段被视图分页器布局切割

Datagrid分页排序删除代码

Oracle分页查询中排序与效率问题

解决Oracle分页查询中排序与效率问题