ページ付けは、ユーザーが前へをクリックできるアプリケーションでよく使用されます。 /次へ 結果を構成するページをナビゲートするか、ページ番号をクリックして特定のページに直接移動します。
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 | +-----------+---------+