我正在尝试返回一个数据页面,并在一个存储过程中返回所有数据的行数,如下所示:
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)但是当我在CTE性能降低时添加 COUNT(x)OVER(PARTITION BY 1)时,通常不需要花费时间的上述查询需要永远执行。我估计这是因为计算了每一行的数量?我似乎无法在另一个查询中重用CTE。 Table Props有100k记录,CTE返回5k记录。
答案 0 :(得分:16)
在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 ...
注意:reedited,大卫现在引用的查询已被垃圾箱查询,查询2现在是查询1。
答案 1 :(得分:1)
您想要整个结果集的计数吗?
这会快速起作用吗?
SELECT *,(select MAX(RowNumber) from Props) as MaxRow
FROM Props
WHERE RowNumber BETWEEN ((@PageNumber - 1) * @PageSize) + 1
AND (@PageNumber * @PageSize);
答案 2 :(得分:1)
我遇到了同样的问题,并且想分享技巧如何返回页面和总行数。 临时表解决的问题。这是存储过程的主体:
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 结果和总行放入临时表,然后选择两个查询。第一个返回总计数,第二个返回页面包含数据。