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