[英]Paging SQL Server 2005 Results
如何在 SQL Server 2005 中分頁結果?
我在 SQL Server 2000 中嘗試過,但沒有可靠的方法來做到這一點。 我現在想知道 SQL Server 2005 是否有任何內置方法?
我所說的分頁是指,例如,如果我按用戶名列出用戶,我希望只能返回前 10 條記錄,然后是接下來的 10 條記錄,依此類推。
任何幫助將非常感激。
您可以使用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
等等
如果你想在一個語句中得到它(總數加上分頁)。 您可能需要探索 SQL Server 對 partition by 子句的支持(ANSI SQL 術語中的窗口函數)。 在 Oracle 中,語法就像上面使用 row_number() 的示例一樣,但我還添加了一個 partition 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
請注意,我擁有 where 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
對此的公認答案實際上對我不起作用......我不得不再跳一個圈才能讓它發揮作用。
當我嘗試答案時
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
然后它起作用了。
當我需要進行分頁時,我通常也會使用臨時表。 您可以使用輸出參數來返回記錄總數。 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
這是我為分頁所做的:我所有需要分頁的大查詢都被編碼為插入到臨時表中。 臨時表有一個標識字段,其作用與上述 row_number() 類似。 我將臨時表中的行數存儲在輸出參數中,以便調用代碼知道總共有多少條記錄。 調用代碼還指定了它想要的頁面以及每頁的行數,這些行是從臨時表中選出的。
這樣做很酷的一點是我還有一個“導出”鏈接,它允許您從我的應用程序中的每個網格上方以 CSV 格式返回的報告中獲取所有行。 此鏈接使用相同的存儲過程:您只需返回臨時表的內容,而不是執行分頁邏輯。 這安撫了討厭分頁、想要查看所有內容並希望以百萬種不同方式對其進行排序的用戶。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.