ページ付けは、ユーザーが前へをクリックできるアプリケーションでよく使用されます。 /次へ 結果を構成するページをナビゲートするか、ページ番号をクリックして特定のページに直接移動します。
SQL Serverでクエリを実行する場合、OFFSETを使用して結果をページ分割できます。 およびFETCH ORDER BYの引数 句。これらの引数はSQLServer2012で導入されたため、SQLServer2012以降を使用している場合はこの手法を使用できます。
このコンテキストでは、ページ付けとは、クエリ結果を小さなチャンクに分割する場所であり、各チャンクは前のチャンクが終了したところから継続します。たとえば、クエリが1000行を返す場合、100行のグループで返されるようにページ分割できます。アプリケーションは、ページ番号とページサイズをSQL Serverに渡すことができ、SQLServerはそれを使用して要求されたページのデータ。
例1-ページネーションなし
まず、テーブル内のすべての行を返すクエリを実行しましょう。
SELECT * FROM Genres ORDER BY GenreId;
結果:
+-----------+---------+ | GenreId | Genre | |-----------+---------| | 1 | Rock | | 2 | Jazz | | 3 | Country | | 4 | Pop | | 5 | Blues | | 6 | Hip Hop | | 7 | Rap | | 8 | Punk | +-----------+---------+
この例ではページネーションを使用していません–すべての結果が表示されます。
この結果セットは非常に小さいため、通常はページネーションは必要ありませんが、この記事の目的上、ページネーションを行いましょう。
例2–最初の3つの結果を表示する
この例では、最初の3つの結果を表示します。
SELECT * FROM Genres ORDER BY GenreId OFFSET 0 ROWS FETCH NEXT 3 ROWS ONLY;
結果:
+-----------+---------+ | GenreId | Genre | |-----------+---------| | 1 | Rock | | 2 | Jazz | | 3 | Country | +-----------+---------+
この場合、結果は最初の結果から開始し、次の3行を表示するように指定します。これは、以下を使用して行われます。
OFFSET 0 ROWSオフセット(ゼロのオフセット)があってはならないことを指定します。-
FETCH NEXT 3 ROWS ONLYオフセットから次の3行を取得します。ゼロのオフセットを指定したので、最初の3行がフェッチされます。
上位3つの結果だけが必要な場合は、TOPを使用して同じ結果を達成できたはずです。 オフセット値とフェッチ値を指定する代わりに句。ただし、これでは次の部分を実行できませんでした。
例3–次の3つの結果を表示する
次の3つの結果を表示しましょう:
SELECT * FROM Genres ORDER BY GenreId OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY;
結果:
+-----------+---------+ | GenreId | Genre | |-----------+---------| | 4 | Pop | | 5 | Blues | | 6 | Hip Hop | +-----------+---------+
ですから、私が変更したのはオフセットだけでした。
オフセット値とフェッチ値は、変数、パラメーター、または定数スカラーサブクエリとして提供される式にすることもできます。サブクエリを使用する場合、外部クエリスコープで定義されている列を参照することはできません(外部クエリと関連付けることはできません)。
次の例では、式を使用して、結果をページ分割する2つのアプローチを示しています。
例4–行番号によるページネーション
この例では、式を使用して行を指定します 開始する番号。
DECLARE
@StartRow int = 1,
@RowsPerPage int = 3;
SELECT *
FROM Genres
ORDER BY GenreId ASC
OFFSET @StartRow - 1 ROWS
FETCH NEXT @RowsPerPage ROWS ONLY;
結果:
+-----------+---------+ | GenreId | Genre | |-----------+---------| | 1 | Rock | | 2 | Jazz | | 3 | Country | +-----------+---------+
ここでは、@StartRow int = 1を使用します 結果を最初の行から開始するように指定します。
その値を2にインクリメントするとどうなりますか。 。
DECLARE
@StartRow int = 2,
@RowsPerPage int = 3;
SELECT *
FROM Genres
ORDER BY GenreId ASC
OFFSET @StartRow - 1 ROWS
FETCH NEXT @RowsPerPage ROWS ONLY;
結果:
+-----------+---------+ | GenreId | Genre | |-----------+---------| | 2 | Jazz | | 3 | Country | | 4 | Pop | +-----------+---------+
2列目から始まります。この方法を使用して、開始する正確な行を指定できます。
例5–ページ番号によるページネーション
この例は、行番号ではなくページ番号を指定できることを除いて、前の例とほとんど同じです。
DECLARE
@PageNumber int = 1,
@RowsPerPage int = 3;
SELECT *
FROM Genres
ORDER BY GenreId ASC
OFFSET (@PageNumber - 1) * @RowsPerPage ROWS
FETCH NEXT @RowsPerPage ROWS ONLY;
結果:
+-----------+---------+ | GenreId | Genre | |-----------+---------| | 1 | Rock | | 2 | Jazz | | 3 | Country | +-----------+---------+
したがって、最初の結果は同じです。ただし、@PageNumberをインクリメントするとどうなるか見てみましょう。 2へ (新しい目的を反映するために、この変数の名前を変更しました。)
DECLARE
@PageNumber int = 2,
@RowsPerPage int = 3;
SELECT *
FROM Genres
ORDER BY GenreId ASC
OFFSET (@PageNumber - 1) * @RowsPerPage ROWS
FETCH NEXT @RowsPerPage ROWS ONLY;
結果:
+-----------+---------+ | GenreId | Genre | |-----------+---------| | 4 | Pop | | 5 | Blues | | 6 | Hip Hop | +-----------+---------+
今回の結果は4行目から始まります。したがって、このメソッドを使用すると、行番号ではなくページ番号を渡すだけで済みます。
例6–ページネーションループ
最後に、すべてのページをループして、各反復の開始行番号を指定する簡単な例を次に示します。
DECLARE
@StartRow int = 1,
@RowsPerPage int = 3;
WHILE (SELECT COUNT(*) FROM Genres) >= @StartRow
BEGIN
SELECT *
FROM Genres
ORDER BY GenreId ASC
OFFSET @StartRow - 1 ROWS
FETCH NEXT @RowsPerPage ROWS ONLY;
SET @StartRow = @StartRow + @RowsPerPage;
CONTINUE
END;
結果:
+-----------+---------+ | GenreId | Genre | |-----------+---------| | 1 | Rock | | 2 | Jazz | | 3 | Country | +-----------+---------+ (3 rows affected) +-----------+---------+ | GenreId | Genre | |-----------+---------| | 4 | Pop | | 5 | Blues | | 6 | Hip Hop | +-----------+---------+ (3 rows affected) +-----------+---------+ | GenreId | Genre | |-----------+---------| | 7 | Rap | | 8 | Punk | +-----------+---------+ (2 rows affected)
例7–行と行
ROWを使用するコードに遭遇した場合 ROWSの代わりに 、両方の引数は同じことをします。これらは同義語であり、ANSI互換性のために提供されています。
これがこのページの最初の例ですが、ROW ROWSの代わりに 。
SELECT * FROM Genres ORDER BY GenreId OFFSET 0 ROW FETCH NEXT 3 ROW ONLY;
結果:
+-----------+---------+ | GenreId | Genre | |-----------+---------| | 1 | Rock | | 2 | Jazz | | 3 | Country | +-----------+---------+
例8– FIRST vs NEXT
同じことがFIRSTにも当てはまります およびNEXT 。これらは、ANSI互換性のために提供されている同義語です。
これは前の例ですが、FIRST NEXTの代わりに 。
SELECT * FROM Genres ORDER BY GenreId OFFSET 0 ROW FETCH FIRST 3 ROW ONLY;
結果:
+-----------+---------+ | GenreId | Genre | |-----------+---------| | 1 | Rock | | 2 | Jazz | | 3 | Country | +-----------+---------+