SQL Server 2005 使用 ROW_NUMBER() 进行过滤和分页

问题描述 投票:0回答:1

我有一个包含数千条记录的表,想要实现分页逻辑。经过一些研究,我发现了 SQL Server 2005 中引入的 ROW_NUMBER() 函数。我的问题是,它似乎不能满足我的确切需求,我想知道如何调整我的存储过程以使其按预期工作:

ALTER PROCEDURE dbo.irweb_Posts_CollectCategoryIdDatesRange
    (
    @CategoryId int,
    @StartDate datetime,
    @EndDate datetime,
    @IsDeleted bit,
    @PageIndex int,
    @PageSize int,
    @Offset int
    )
AS
    DECLARE @TotalRecords   int

    SELECT @TotalRecords = (
        SELECT COUNT(irweb_Posts.PostId) 
        FROM irweb_Posts 
        WHERE (IsDeleted = @IsDeleted)
        AND (CategoryId = @CategoryId)
    AND (DateCreated >= @StartDate) 
    AND (DateCreated <= @EndDate)           
    )

    SELECT * 
    FROM (
        SELECT  ROW_NUMBER() OVER (ORDER BY DateCreated DESC) AS RowId, irweb_Posts.*
        FROM      irweb_Posts
        ) AS p
    WHERE   ((IsDeleted = @IsDeleted)
        AND (CategoryId = @CategoryId)
        AND (DateCreated >= @StartDate) 
        AND (DateCreated <= @EndDate)       
        AND ((RowId > @Offset) AND (RowId <= (@Offset + @PageSize))))   

    RETURN @TotalRecords

如果我执行这个存储过程,我会得到以下结果

Running [dbo].[irweb_Posts_CollectCategoryIdDatesRange] ( 
@CategoryId = 7, 
@StartDate = 5/1/2009 12:00:00 AM, 
@EndDate = 5/31/2009 11:59:59 PM, 
@IsDeleted = False, 
@PageIndex = 0, 
@PageSize = 20, 
@Offset = 0 ).

RowId                 PostId      CategoryId  ParentId    
--------------------- ----------- ----------- ----------- 
No rows affected.
(0 row(s) returned)
@RETURN_VALUE = 609
Finished running [dbo].[irweb_Posts_CollectCategoryIdDatesRange].


Running [dbo].[irweb_Posts_CollectCategoryIdDatesRange] ( 
@CategoryId = 7, 
@StartDate = 5/1/2009 12:00:00 AM, 
@EndDate = 5/31/2009 11:59:59 PM, 
@IsDeleted = False, 
@PageIndex = 0, 
@PageSize = 210, 
@Offset = 0 ).

RowId                 PostId      CategoryId  ParentId    
--------------------- ----------- ----------- ----------- 
205                   1173        7           0           
206                   1169        7           0           
207                   1168        7           0           
208                   1167        7           0           
209                   1165        7           0           
210                   1164        7           0           
No rows affected.
(6 row(s) returned)
@RETURN_VALUE = 609
Finished running [dbo].[irweb_Posts_CollectCategoryIdDatesRange].

行号字段似乎没有像预期的那样从 1 开始。我怀疑整个表的起始值是 1,而不是过滤后的结果集。如果我不需要对过滤记录进行分页,那不会是问题。我怎样才能做到这一点?

pagination sql-server-2005
1个回答
7
投票

将 where 子句移至内部,并将行号检查保留在外部

SELECT *     
FROM (        
        SELECT  ROW_NUMBER() OVER (ORDER BY DateCreated DESC) AS RowId, irweb_Posts.*        
        FROM      irweb_Posts        
        WHERE   (   (IsDeleted = @IsDeleted)        
            AND (CategoryId = @CategoryId)        
            AND (DateCreated >= @StartDate)         
            AND (DateCreated <= @EndDate))
    ) as p    
WHERE ((RowId > @Offset) AND (RowId <= (@Offset + @PageSize)))
© www.soinside.com 2019 - 2024. All rights reserved.