簡體   English   中英

分頁 SQL Server 2005 結果

[英]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

我相信您需要執行一個單獨的查詢來實現這一點。

我能夠使用此頁面的一些幫助在我以前的職位上完成此操作: DotNet 2.0 中的分頁

他們也有它單獨拉行數。

這是我為分頁所做的:我所有需要分頁的大查詢都被編碼為插入到臨時表中。 臨時表有一個標識字段,其作用與上述 row_number() 類似。 我將臨時表中的行數存儲在輸出參數中,以便調用代碼知道總共有多少條記錄。 調用代碼還指定了它想要的頁面以及每頁的行數,這些行是從臨時表中選出的。

這樣做很酷的一點是我還有一個“導出”鏈接,它允許您從我的應用程序中的每個網格上方以 CSV 格式返回的報告中獲取所有行。 此鏈接使用相同的存儲過程:您只需返回臨時表的內容,而不是執行分頁邏輯。 這安撫了討厭分頁、想要查看所有內容並希望以百萬種不同方式對其進行排序的用戶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM