使用Top和Count的最佳方法 - SQL Server 2008

时间:2011-07-07 15:47:03

标签: c# sql-server-2008

我有一个2008 C#应用程序(后端SQL Server 2008),有时查询会返回大量结果。因此,我研究了一些分页算法,并使用TOP语句。我喜欢这样一个事实,即如果我总共有500个结果并且每页只显示20个结果,那么我只能在数据库中查询20条记录,而不是将所有500条记录存储在内存中。

我遇到的问题是,为了实现分页算法,我需要知道此查询中有多少总记录。所以,我所做的只是运行另一个查询,使用相同的参数只选择ID(而不是整个对象)来尝试使其快速运行。出于某种原因,我认为运行这两个查询(从而建立2个连接)并不是最好的方法。

所以我需要记录所有的计数,但只想选择TOP中使用的有限数量。临时桌会在这里使用吗?我现在有两个不同的存储过程。

感谢任何人都能给出的“最佳实践”建议。

5 个答案:

答案 0 :(得分:0)

您可以使用object datasource ...来实现此自定义分页。

答案 1 :(得分:0)

我会使用ROW_NUMBER() OVER (ORDER BY ...)。更多详情here

答案 2 :(得分:0)

我不知道你采用什么方法进行分页,但我通常使用的技术是使用ROW_NUMBER函数,例如:

SELECT  Description, Date
FROM
(
    SELECT  ROW_NUMBER() OVER (ORDER BY Date DESC) AS Row,
        Description, Date 
    FROM Log
) AS LogWithRowNumbers
WHERE  Row >= 1 AND Row <= 10

这种方法是我所知道的最简洁,适用于任何子查询,只需要一个查询。

当然,如果您希望在页面上显示“总点击次数”或类似内容,那么您还需要另一个查询来获取行数:

SELECT COUNT(*) FROM Log

但是,您可以在同一批次中执行这两个语句,以防止需要对数据库服务器进行额外的“往返”。

来源 - Paging Records Using SQL Server 2005 Database - ROW_NUMBER Function

答案 3 :(得分:0)

如果在存储过程中同时执行两个选择,则在使用Fill方法后,您将在数据集中获得两个数据表。

答案 4 :(得分:0)

我会尝试这样的事情:

;WITH CTE AS
(
    SELECT 
        ROW_NUMBER() OVER (ORDER BY Date DESC) AS Row,
        COUNT(*) OVER() AS TotalCount,
        Description, Date 
    FROM Log
)

SELECT *
FROM CTE
WHERE Row BETWEEN 1 AND 10

这将在1个查询中提供分页和计数。您还可以使用CASE语句仅在特定时间执行计数。例如,当用户进行翻页时,计数是否会发生变化?