在我的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
答案 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