MSSQL 2008 SP分页和计数总记录数

时间:2010-11-08 12:12:04

标签: sql sql-server sql-server-2008 stored-procedures

在我的SP中,我有以下内容:

with Paging(RowNo, ID, Name, TotalOccurrences) as 
(
    ROW_NUMBER() over (order by TotalOccurrences desc) as RowNo, V.ID, V.Name, R.TotalOccurrences FROM dbo.Videos V INNER JOIN .... 
)
SELECT * FROM Paging WHERE RowNo BETWEEN 1 and 50
SELECT COUNT(*) FROM Paging

结果是我收到错误:无效的对象名称'Paging'。 我可以再次查询分页表吗?我不想将所有结果的计数作为新列包含在内......我宁愿将其作为另一个数据集返回。这可能吗?

谢谢,Radu

4 个答案:

答案 0 :(得分:2)

经过更多研究后,我找到了另一种方法:

with Paging(RowNo, ID, Name, TotalOccurrences) AS
(
    ROW_NUMBER() over (order by TotalOccurrences desc) as RowNo, V.ID, V.Name,    R.TotalOccurrences FROM dbo.Videos V INNER JOIN .... 
)
select  RowNo, ID, Name, TotalOccurrences, (select COUNT(*) from Paging) as TotalResults  from Paging where RowNo between (@PageNumber - 1 )* @PageSize + 1 and @PageNumber * @PageSize;

我认为这比调用两次查询具有更好的性能。

答案 1 :(得分:1)

您不能这样做,因为您定义的CTE仅可用于定义后出现的FIRST查询。因此,当您运行COUNT(*)查询时,CTE不再可用于引用。这只是CTE的限制。

因此,要将COUNT作为单独的步骤,您需要不使用CTE,而是使用完整查询来COUNT开启。 或者,您可以将CTE包装在内联表值函数中,然后使用它来保存重复主查询,如下所示:

CREATE FUNCTION dbo.ufnExample() 
    RETURNS TABLE
AS
RETURN
(
with Paging(RowNo, ID, Name, TotalOccurrences) as 
(
    ROW_NUMBER() over (order by TotalOccurrences desc) as RowNo, V.ID, V.Name, R.TotalOccurrences FROM dbo.Videos V INNER JOIN .... 
)
SELECT * FROM Paging
)

SELECT * FROM dbo.ufnExample() x WHERE RowNo BETWEEN 1 AND 50
SELECT COUNT(*) FROM dbo.ufnExample() x

答案 2 :(得分:1)

请注意,Radu D的解决方案的查询计划显示了对这些表的双重命中。它正在进行两次处决。但是,这仍然是最好的方法,因为我还没有找到真正可扩展的1查询设计。

不太可扩展的1查询设计是将已完成的有序列表转储到@tablevariable,SELECT @@ ROWCOUNT以获取完整计数,并从@table变量中选择X和Y之间的行号。这适用于&lt ; 10000行,但结果数百万行,填充@tablevariable变得昂贵。

混合方法是将此临时值/变量填充到10000行。如果并非所有10000行都已填满,那么您已设置好。如果填充10000行,则需要重新运行搜索才能获得完整计数。如果大多数查询返回10000行以下,这很有效。 10000限制是一个粗略的近似值,您可以根据您的情况使用此阈值。

答案 3 :(得分:0)

在CTE表名称Paging之后写下“AS”,如下所示: 使用Paging AS(RowNo,ID,Name,TotalOccurrences)作为
(     ROW_NUMBER()结束(按TotalOccurrences desc排序)为RowNo,V.ID,V.Name,R.TotalOccurrences FROM dbo.Videos V INNER JOIN ....
) SELECT * FROM Paging WHERE RowNo BETWEEN 1和50 SELECT COUNT(*)FROM Paging