Sql server 使用行号时从SQL Server返回总记录

Sql server 使用行号时从SQL Server返回总记录,sql-server,paging,sql-server-2008-r2,Sql Server,Paging,Sql Server 2008 R2,我想返回数据库中的记录总数,以便设置分页。在SQLServer2008中使用以下分页方法时,如何返回数据库中的记录总数 ALTER PROCEDURE [dbo].[Nop_LoadAllOptimized] ( @PageSize int = 20, @PageNumber int = 1, @WarehouseCombinationID int = 1, @CategoryId int = 58,

我想返回数据库中的记录总数,以便设置分页。在SQLServer2008中使用以下分页方法时,如何返回数据库中的记录总数

    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

我通常是这样做的-从性能角度看,我从未真正检查过它是否非常有效:

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
基本上,如果您的CTE中没有分区BY,则RowNum值的值为1到行总数,因此选择MAXRowNum,您将获得行总数。

我以前使用过临时表,但发现了另一个使用Count的解决方案。。请转到以查找几天前的行总数。它的工作原理如下:

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

参考页是。

See@Martin这就是我所看到的,但没有说明如何返回总行数?我编辑了我的评论并更改了链接。你指的是哪个链接?SQLServerCentral还是StackOverflow?顺便说一句,正是它涵盖了这一点。@Martin,谢谢你的编辑。这样,它会将TotalRows列添加到我的记录集中。如何将TotalRows指定为输出参数?谢谢。如何将TotalRows分配给存储过程中的输出参数?它可以双向工作,您的和Martins,但希望将其作为参数返回,而不是作为数据集中的新列返回。编辑,明白了:@TotalRecords=PG.totalrowsv真聪明!对我来说效果很好,速度也很快。你应该用Count*替换MaxRowNum字段。Count的执行速度要快得多,至少在我的查询中是这样。如何将TotalRows分配给@TotalRecords int=null输出?对象名称“MyCTE”无效。我尝试了这个SELECT@TotalRecords=SELECT MAXRowNumber FROM MyCTE SELECT Id,Name FROM MyCTE WHERE rowname FROM Start AND End。我认为CTE只适用于一个立即选择语句。这是迄今为止我找到的解决此问题的最佳方案。具有不会显著影响查询执行时间的优点。这里的问题是不能在WHERE子句中使用RowNo。我知道这是旧的解决方案,但此解决方案比上面介绍的解决方案要好得多。Fedor指出,RowNo不能在WHERE子句中使用,但如果该查询是封闭的,则可以使用它:从VillageidiotsQuery中选择*作为子查询,其中RowNo介于1和2之间