12

我正在尝试在一个存储过程中返回一页数据以及所有数据的行数,如下所示:

WITH Props AS
(
    SELECT *,
    ROW_NUMBER() OVER (ORDER BY PropertyID) AS RowNumber
    FROM Property
    WHERE PropertyType = @PropertyType AND ...
)   

SELECT * FROM Props 
WHERE RowNumber BETWEEN ((@PageNumber - 1) * @PageSize) + 1 AND (@PageNumber * @PageSize);

我无法返回行数(最高行数)。

我知道这已经被讨论过了(我已经看到了: Efficient way of getting @@rowcount from a query using row_number)但是当我添加COUNT(x) OVER(PARTITION BY 1)CTE 时,性能会下降,并且上面通常不需要时间的查询需要永远执行。我认为这是因为计数是针对每一行计算的?我似乎无法在另一个查询中重用 CTE。Table Props 有 100k 条记录,CTE 返回 5k 条记录。

4

3 回答 3

20

在 T-SQL 中应该是

;WITH Props AS
(
    SELECT *,
        ROW_NUMBER() OVER (ORDER BY PropertyID) AS RowNumber
    FROM Property
    WHERE PropertyType = @PropertyType AND ...
)

, Props2 AS
(
    SELECT COUNT(*) CNT FROM Props
)

-- Now you can use even Props2.CNT
SELECT * FROM Props, Props2
WHERE RowNumber BETWEEN ((@PageNumber - 1) * @PageSize) + 1 AND (@PageNumber * @PageSize);

现在你在每一行都有CNT......或者你想要一些不同的东西?你想要一个只有计数的第二个结果集?那就去做吧!

-- This could be the second result-set of your query.
SELECT COUNT(*) CNT
FROM Property
WHERE PropertyType = @PropertyType AND ...

注意:重新编辑,大卫现在引用的查询 1 已被丢弃,查询 2 现在是查询 1。

于 2011-09-15T20:07:21.973 回答
1

你想要整个结果集的计数吗?

这能快速工作吗?

SELECT *,(select MAX(RowNumber) from Props) as MaxRow 
FROM Props 
WHERE RowNumber BETWEEN ((@PageNumber - 1) * @PageSize) + 1 
    AND (@PageNumber * @PageSize);
于 2011-09-15T19:59:48.350 回答
1

我遇到了同样的问题,想分享返回 page 和 total rows的代码。该问题由临时表解决。这是存储过程的主体:

DECLARE @personsPageTable TABLE(
  RowNumber INT, 
  PersonId INT, 
  FirstName NVARCHAR(50), 
  LastName NVARCHAR(50), 
  BirthDate DATE, 
  TotalCount INT);
    
        ;WITH PersonPage AS 
        (
            SELECT 
                 ROW_NUMBER() OVER(ORDER BY persons.Id) RowNumber,
                 Id,
                 FirstName,
                 LastName,
                 BirthDate
            FROM Persons
            WHERE BirthDate >= @BirthDateFrom AND BirthDate <= @BirthDateTo
        ), TotalCount AS( SELECT COUNT(*) AS [Count] FROM PersonPage)
        INSERT INTO @personsPageTable
        SELECT *, (select * from TotalCount) TotalCount FROM PersonPage
        ORDER BY PersonPage.RowNumber ASC
        OFFSET ((@pageNumber - 1) * @pageSize) ROWS
        FETCH NEXT @pageSize ROWS ONLY
    
        SELECT TOP 1 TotalCount FROM @personsPageTable
    
        SELECT 
            PersonId, 
            FirstName, 
            LastName, 
            BirthDate
        FROM @personsPageTable

如您所见,我将 CTE结果和总行数放入临时表并选择两个查询。第一个返回总计数,第二个返回带有数据的页面。

于 2018-11-22T12:55:49.077 回答