2008-08-05 125 views
36

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

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

我的意思分页,例如,如果我列出用户可以通过自己的用户名,我希望能够只返回前10条记录,那么接下来的10条记录等等。

任何帮助将不胜感激。

回答

33

可以使用the 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

优秀的,简单的例子帕特 - 正是我一直在后:) – Town 2009-09-18 09:59:53

+0

这个答案对我来说是不行的,但它确实让我更接近。它抱怨说它不知道RowID是什么。如果您遇到同样的问题,请参阅下面的答案以获取更多信息。 – Beska 2009-09-25 19:02:26

+2

在内部的选择,你可以( - 10在这种情况下,X = MAX行希望)选择TOP X行。它会提高查询的速度。 – Faruz 2010-01-05 08:18:54

0

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

他们也有它拉一排seperately数:

我使用此页一些帮助才得以在我以前的位置来实现这一点。

0

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

关于做这种方式很酷的事情是,我也有一个“出口”链接,使你获得的所有行报告返回CSV在我的应用程序中每个网格上方。该链接使用相同的存储过程:只需返回临时表的内容而不是执行分页逻辑。这安抚了讨厌寻呼的用户,并且想要看的一切,并且想要以一百万种不同的方式对其进行排序。

13

如果你想获得它在一个声明(总正极分页)。您可能需要探索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 

请注意,我有哪里owner ='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 
2

当我需要做分页时,我通常也使用临时表。您可以使用输出参数来返回记录总数。 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 
5

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

当我试图回答

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

它失败了,抱怨说这不知道是什么行ID了。

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

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

,然后它的工作。