2009-12-07 5 views
2

J'ai une table appelée avec des milliers d'enregistrements et j'aimerais implémenter la logique de pagination. Après avoir fait quelques recherches, je suis tombé sur la fonction ROW_NUMBER() introduite dans SQL Server 2005. Mon problème est, il semble ne pas répondre à mes besoins et je me demande comment modifier ma procédure stockée pour qu'elle fonctionne comme prévu:Filtrage et pagination SQL Server 2005 avec 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 

Si j'exécute cette procédure stockée, je reçois les résultats suivants

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

il semble que le champ de numéro de ligne ne démarre pas à 1 comme il est censé. Je soupçonne qu'il commence à 1 pour toute la table et non le jeu de résultats filtré. Ce ne serait pas un problème si je n'exige pas la pagination des enregistrements filtrés. Comment puis-je faire ce travail?

Répondre

7

Déplacer la clause where à l'intérieur et laisser le numéro de ligne chèque extérieur

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))) 
+0

Oh Wow! Merci un million. J'avais essayé cela auparavant, mais j'ai omis la clause "AS" - n'a pas fonctionné. Je n'y ai pas pensé ... Encore une fois, merci! –

+0

Je sais que ce sujet est bien fermé, mais pour une simple sélection de pagination, c'est remarquable. il y a tellement de solutions compliquées là-bas. ça berce simplement. – horace