分页SQL Server 2005结果

如何在SQL Server 2005中分页结果?

我在SQL Server 2000中试过,但没有可靠的方法来做到这一点。我现在想知道SQL Server 2005是否有内置方法?

我的意思是分页,例如,如果我通过用户名列出用户,我希望只能返回前10条记录,然后是下10条记录等等。

任何帮助将非常感激。

0
额外 编辑
意见: 1

6 答案

您可以使用 Row_Number()函数。 它的用法如下:

SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users

从中可以得到带有 RowID 字段的结果集,您可以使用该字段在页面之间进行换页。

SELECT * 
FROM 
    ( SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
      FROM Users 
    ) As RowResults
WHERE RowID Between 5 AND 10

等等

0
额外
这个答案对我来说不起作用,尽管它让我更加接近。它抱怨说它不知道RowID是什么。如果您遇到同样的问题,请参阅下面的答案以获取更多信息。
额外 作者 Beska,
优秀,简单的例子帕特 - 正是我之后:)
额外 作者 Town,
在内部选择中,您可以选择TOP X行(X =最大行数,在本例中为10)。它会提高查询的速度。
额外 作者 Faruz,
正如我上面提到的评论者,加入改善这种代码的性能<�代码> TOP </代码>的内表:<�代码> SELECT TOP 10 ROW_NUMBER()OVER ... </代码>你只抢将需要的行,而不是整个表。
额外 作者 Doug S,

我相信你会需要执行一个单独的查询来实现这一目标unfortionately。

I was able to accomplish this at my previous position using some help from this page: Paging in DotNet 2.0

他们也让它单独计数。

0
额外

以下是我为分页所做的工作:所有需要分页的大型查询都被编码为插入到临时表中。临时表有一个标识字段,其行为与上面提到的row_number()类似。我将临时表中的行数存储在输出参数中,以便调用代码知道有多少个总记录。调用代码还指定要从哪个页面中选择哪个页面,以及每个页面有多少行,这些行是从临时表中选出的。

关于这样做的很酷的事情是,我还有一个“导出”链接,允许您从报表中以CSV格式返回报表中的所有行,并位于应用程序中的每个网格上方。该链接使用相同的存储过程:只需返回临时表的内容而不是执行分页逻辑。这安抚了那些讨厌分页,希望看到 的用户,并希望以一百多种不同的方式进行分类。

0
额外

为此接受的答案实际上并不适用于我...我不得不跳过一个环来让它工作。

当我试着回答

SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users
WHERE RowID Between 0 AND 9

它失败了,抱怨说它不知道RowID是什么。

我不得不把它包装在这样的内部选择中:

SELECT * 
FROM
    (SELECT
    Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
    FROM Users
    ) innerSelect
WHERE RowID Between 0 AND 9

然后它工作。

0
额外

如果你想用一个语句(总数加上分页)来获得它。您可能需要探索SQL Server对分区依据子句的支持(ANSI SQL术语中的窗口函数)。在Oracle中,语法与上面使用row_number()的示例类似,但我还添加了分区by子句,以获取分页中返回的每行所包含的总行数(总行数为1,262):

SELECT rn, total_rows, x.OWNER, x.object_name, x.object_type
FROM (SELECT COUNT (*) OVER (PARTITION BY owner) AS TOTAL_ROWS,
         ROW_NUMBER() OVER (ORDER BY 1) AS rn, uo.*
         FROM all_objects uo
         WHERE owner = 'CSEIS') x
WHERE rn BETWEEN 6 AND 10

请注意,我拥有所有者='CSEIS',并且我的分区位于所有者。所以结果是:

RN  TOTAL_ROWS  OWNER   OBJECT_NAME            OBJECT_TYPE
6   1262    CSEIS   CG$BDS_MODIFICATION_TYPES   TRIGGER
7   1262    CSEIS   CG$AUS_MODIFICATION_TYPES   TRIGGER
8   1262    CSEIS   CG$BDR_MODIFICATION_TYPES   TRIGGER
9   1262    CSEIS   CG$ADS_MODIFICATION_TYPES   TRIGGER
10  1262    CSEIS   CG$BIS_LANGUAGES            TRIGGER
0
额外
+1我想知道如何获得总行和页面而不使用临时表。谢谢!!
额外 作者 dotjoe,
+1 ...很好。现在玩它:-)你知道使用COUNT(*)OVER(...)的任何性能打击吗?
额外 作者 Chris J,
+1很好 - 它使用COUNT(*)OVER(PARTITION BY NULL)在sqlserver上工作。
额外 作者 Hafthor,
一般来说,您可以直接在SQL中执行的任何操作都是最佳选择。换句话说,无论您是在单个SQL查询中执行的任何操作,都可能会比Java / pl / SQL C#更具编程特色。请尽量阅读Kyte先生: tkyte.blogspot.com/2006 /10/slow-by-slow.html
额外 作者 Brian,

当我需要分页时,我通常也使用临时表。您可以使用输出参数来返回记录总数。 select中的case语句允许您对特定列上的数据进行排序,而不需要求助于动态SQL。

--Declaration--

--Variables
@StartIndex INT,
@PageSize INT,
@SortColumn VARCHAR(50),
@SortDirection CHAR(3),
@Results INT OUTPUT

--Statements--
SELECT @Results = COUNT(ID) FROM Customers
WHERE FirstName LIKE '%a%'

SET @StartIndex = @StartIndex - 1 --Either do this here or in code, but be consistent
CREATE TABLE #Page(ROW INT IDENTITY(1,1) NOT NULL, id INT, sorting_1 SQL_VARIANT, sorting_2 SQL_VARIANT)
INSERT INTO #Page(ID, sorting_1, sorting_2)
SELECT TOP (@StartIndex + @PageSize)
    ID,
    CASE
        WHEN @SortColumn='FirstName' AND @SortDirection='ASC' THEN CAST(FirstName AS SQL_VARIANT)
        WHEN @SortColumn='LastName' AND @SortDirection='ASC' THEN CAST(LastName AS SQL_VARIANT)
        ELSE NULL
    END AS sort_1,
    CASE
        WHEN @SortColumn='FirstName' AND @SortDirection='DES' THEN CAST(FirstName AS SQL_VARIANT)
        WHEN @SortColumn='LastName' AND @SortDirection='DES' THEN CAST(LastName AS SQL_VARIANT)
        ELSE NULL
    END AS sort_2
FROM (
    SELECT
        CustomerId AS ID,
        FirstName,
        LastName
    FROM Customers
    WHERE
        FirstName LIKE '%a%'
) C
ORDER BY sort_1 ASC, sort_2 DESC, ID ASC;

SELECT
    ID,
    Customers.FirstName,
    Customers.LastName
FROM #Page
INNER JOIN Customers ON
    ID = Customers.CustomerId
WHERE ROW > @StartIndex AND ROW <= (@StartIndex + @PageSize)
ORDER BY ROW ASC

DROP TABLE #Page
0
额外
这是你将在Sql Server 2000中做的事情,但2005版本使用ROW_NUMBER函数有更好的解决方案。
额外 作者 niaher,