我有一个程序来返回一个受页码和其他东西限制的结果集.作为OUTPUT参数,我需要根据除页码之外的参数返回所选行的总量.所以我有类似的东西:
WITH SelectedItems AS (SELECT Id, Row1, Row2, ROW_NUMBER() OVER (ORDER BY Row1) AS Position FROM Items WHERE Row2 = @Row2) SELECT Id, Row1, Row2 FROM SelectedItems WHERE Position BETWEEN @From AND @To
然后我需要将OUTPUT参数设置为内部查询中的行数.我可以复制查询并对其进行计数,但是这个查询可能会返回数千行(并且将来会更多),所以我正在寻找方法来实现这一点并获得良好的性能.我在考虑表变量,这是个好主意吗?还是其他任何建议?
更具体地说,它是Microsoft SQL Server 2008.
谢谢你,Jan
您可以使用COUNT(*)将总行数计入主查询中的单独列.像这样:
WITH SelectedItems AS (SELECT Id, Row1, Row2, ROW_NUMBER() OVER (ORDER BY Row1) AS Position, COUNT(*) OVER () AS TotalRows FROM Items WHERE Row2 = @Row2) SELECT Id, Row1, Row2 FROM SelectedItems WHERE Position BETWEEN @From AND @To
这将返回结果集中的计数而不是输出参数,但这应该符合您的要求.否则,与临时表结合使用:
DECLARE @tmp TABLE (Id int, RowNum int, TotalRows int); WITH SelectedItems AS (SELECT Id, Row1, Row2, ROW_NUMBER() OVER (ORDER BY Row1) AS Position, COUNT(*) OVER () AS TotalRows FROM Items WHERE Row2 = @Row2) INSERT @tmp SELECT Id, Row1, Row2 FROM SelectedItems WHERE Position BETWEEN @From AND @To SELECT TOP 1 @TotalRows = TotalRows FROM @tmp SELECT * FROM @tmp
您会发现使用临时表只是为了您的分页结果不会占用太多内存(当然,这取决于您的页面大小),并且您只能在短时间内保持活动状态.从临时表中选择完整的结果集并选择TotalRows只需要更长的时间.
这将比运行完全独立的查询快得多,在我的测试中(重复WITH)将执行时间加倍.