2010-11-08 85 views
1

在我的SP号码,我有以下几点:MSSQL 2008 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 

结果是我得到的错误:无效的对象名称“寻呼”。 我可以再次查询分页表吗?我不希望将所有结果的计数作为新列加入......我宁愿将其作为另一个数据集返回。那可能吗?

感谢,拉杜

回答

2

更多的研究,我喜欢这样做的另一种方式后: 或者,你可以在内嵌表值函数并使用它,保存重复主查询,这样的包裹CTE了

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; 

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

+0

这不是最快的,我现在花很多时间在这个上面工作。最快的解决方案是获得一个RowNo,也是一个ReverseRowNo(相反排序),然后通过执行“TotalRecords = RowNo + ReverseRowNo - 1”来计算Total。试试大数据集 - 大量改进。 – 2013-12-03 21:35:14

0

写 “为” CTE表名寻呼如下之后: 与寻呼AS(RowNo,ID,姓名,TotalOccurrences)为
( ROW_NUMBER()OVER(由TotalOccurrences秩序(*),来自dbo.Videos V INNER JOIN ....
) SELECT * FROM PAING WHERE RowNo BETWEEN 1 and 50 SELECT COUNT(*)FROM Paging

1

你不能这样做,因为你正在定义的CTE将o只有在定义后出现的FIRST查询才可用。因此,当您运行COUNT(*)查询时,CTE不再可供引用。这只是CTE的限制。

因此,要将COUNT作为单独的步骤执行,您需要不使用CTE,而是将完整查询用于COUNT。

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 
1

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

可扩展性较差的1查询设计是将已完成的有序列表转储到@tablevariable,SELECT @@ ROWCOUNT以获取完整计数,并从@tablevariable中选择X和Y之间的行数。此操作适用于< 10000行,但结果在数百万行中,填充@tablevariable变得非常昂贵。

混合方法是将此temp /变量填充到10000行。如果不是全部10000行都填满了,那么就设置好了。如果填满10000行,则需要重新运行搜索以获得完整的计数。如果大多数查询返回10000行以下,这很好。 10000的限制是一个粗略的近似值,您可以针对您的情况使用此阈值。

+0

避免使用临时表或表变量非常快地在大型数据集上进行查询。您仍然可以完成获取TotCount而不必创建临时表,请参阅我的其他评论。 – 2013-12-03 21:36:35