SQL Server 2005 使用 ROW_NUMBER() 进行过滤和分页
我有一个包含数千条记录的表,想要实现分页逻辑。经过一些研究,我发现了 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
将 where 子句移至内部,并将行号检查保留在外部
Move the where clause inside and leave the row number check outside