質問

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

他のヒント

1 つのステートメント (合計とページング) で取得しようとしている場合。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' があり、パーティション by が所有者にあることに注意してください。結果は次のようになります。

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

これに対する受け入れられている答えは、実際には私にとっては機能しません...機能させるには、もう1つのフープを飛び越える必要がありました。

答えを試してみたところ

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() と同様の方法で動作する ID フィールドがあります。一時テーブルの行数を出力パラメータに保存することで、呼び出し元のコードが合計レコード数を認識できるようにします。呼び出しコードでは、必要なページと、一時テーブルから選択されるページごとの行数も指定します。

この方法の優れた点は、アプリケーションの各グリッド上に CSV として返されたレポートからすべての行を取得できる「エクスポート」リンクも用意されていることです。このリンクでは、同じストアド プロシージャを使用します。ページング ロジックを実行する代わりに、一時テーブルの内容を返すだけです。これにより、ページングを嫌うユーザーをなだめることができます。 すべて, 、それを何百万もの異なる方法で並べ替えたいと考えています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top