SQL Server 2005 фильтрация и разбиение на страницы с помощью ROW_NUMBER () - PullRequest
2 голосов
/ 07 декабря 2009

У меня есть таблица с тысячами записей, и я хотел бы реализовать логику подкачки. Проведя некоторые исследования, я натолкнулся на функцию ROW_NUMBER (), представленную в SQL Server 2005. Моя проблема в том, что она, похоже, не соответствует моим точным потребностям, и мне интересно, как настроить мою хранимую процедуру, чтобы она работала, как ожидалось: 1001 *

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 для всей таблицы, а не отфильтрованного набора результатов. Это не будет проблемой, если мне не потребуется подкачка отфильтрованных записей. Как я могу сделать эту работу?

1 Ответ

7 голосов
/ 07 декабря 2009

Переместите предложение 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)))
...