Возвращать итоговые записи из SQL Server при использовании ROW_NUMBER - PullRequest
30 голосов
/ 26 апреля 2011

Я хотел бы вернуть общее количество записей в базе данных, чтобы я мог настроить нумерацию страниц.Как вернуть общее количество записей в БД при использовании следующего метода подкачки в SQL Server 2008?

    ALTER PROCEDURE [dbo].[Nop_LoadAllOptimized]
    (
        @PageSize int = 20,
        @PageNumber int = 1,
        @WarehouseCombinationID int = 1,
        @CategoryId int = 58,
        @OrderBy int = 0,
        @TotalRecords int = null OUTPUT
    )
    AS
    BEGIN
    WITH Paging AS (
        SELECT rn = (ROW_NUMBER() OVER (
        ORDER BY 
            CASE WHEN @OrderBy = 0 AND @CategoryID IS NOT NULL AND @CategoryID > 0
            THEN pcm.DisplayOrder END ASC,
            CASE WHEN @OrderBy = 0
            THEN p.[Name] END ASC,
            CASE WHEN @OrderBy = 5
            THEN p.[Name] END ASC,
            CASE WHEN @OrderBy = 10
            THEN wpv.Price END ASC,
            CASE WHEN @OrderBy = 15
            THEN wpv.Price END DESC,
            CASE WHEN @OrderBy = 20
            THEN wpv.Price END DESC,
            CASE WHEN @OrderBy = 25
            THEN wpv.UnitPrice END ASC  
        )), p.*, pcm.DisplayOrder, wpv.Price, wpv.UnitPrice FROM Nop_Product p
        INNER JOIN Nop_Product_Category_Mapping pcm ON p.ProductID=pcm.ProductID
        INNER JOIN Nop_ProductVariant pv ON p.ProductID = pv.ProductID
        INNER JOIN Nop_ProductVariant_Warehouse_Mapping wpv ON pv.ProductVariantID = wpv.ProductVariantID
        WHERE pcm.CategoryID = @CategoryId AND (wpv.Published = 1 AND pv.Published = 1 AND p.Published = 1 AND p.Deleted = 0)
        AND wpv.WarehouseID IN (select WarehouseID from Nop_WarehouseCombination where UserWarehouseCombinationID = @WarehouseCombinationID)    
    )
    SELECT TOP (@PageSize) * FROM Paging PG
    WHERE PG.rn > (@PageNumber * @PageSize) - @PageSize 

    SET @TotalRecords = @@ROWCOUNT 

    END

Ответы [ 2 ]

60 голосов
/ 26 апреля 2011

Обычно я делаю это так - никогда не проверял, насколько это эффективно с точки зрения производительности:

WITH YourCTE AS 
(
   SELECT 
       (list of columns),
       ROW_NUMBER() OVER (ORDER BY ......) AS 'RowNum' 
   FROM dbo.YourBaseTable
)
SELECT 
    *,
    (SELECT MAX(RowNum) FROM YourCTE) AS 'TotalRows' 
FROM 
    YourCTE
WHERE   
    RowNum BETWEEN 101 AND 150

По существу, значение RowNum будет иметь значения от 1 до общего количества строк (если у вас нет PARTITION BY в вашем CTE), и, таким образом, выбрав MAX(RowNum), вы получите общее количество строк.

27 голосов
/ 29 апреля 2013

Ну, я использовал #temp таблицы в прошлом, но нашел другое решение, использующее Count(..) OVER(), чтобы найти общее количество строк несколько дней назад. Это работает примерно так:

SELECT COUNT(id) OVER() [Total], ROW_NUMBER() OVER(ORDER BY id DESC) [RowNo]
, [other columns]
FROM Table

Ссылочная страница здесь .

...