2008-08-05 168 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 

,然後它的工作。