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

发布于 2024-08-13 10:45:00 字数 2521 浏览 8 评论 0原文

我有一个包含数千条记录的表,想要实现分页逻辑。经过一些研究,我发现了 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,而不是过滤后的结果集。如果我不需要对过滤记录进行分页,那不会是问题。我怎样才能做到这一点?

I have a table called with thousands of records and would like to implement paging logic. After doing some research, I came across the ROW_NUMBER() function introduced in SQL Server 2005. My problem is, it seems to not meet my exact need and I'm wondering how to tweak my stored procedure to make it work as expected:

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

If I execute this stored procedure, I get the following results

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].

It seems the row number field is not starting at 1 like it is supposed to. I suspect it starts at 1 for the whole table not the filtered result set. That would not be a problem if I do not require paging of filtered records. How can I make this work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

少女情怀诗 2024-08-20 10:45:00

将 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)))

Move the where clause inside and leave the row number check outside

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)))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文