サーチ…


前書き

行のオフセットとSQL Serverのさまざまなバージョンでのページング

構文

  • SELECT * FROM TableName ORDER BY idオフセット10行FETCH NEXT 10行のみ;

ROW_NUMBERを使用した共通テーブル式によるページネーション

SQL Server 2008

ROW_NUMBER関数は、結果セットの各行に増分番号を割り当てることができます。 BETWEEN演算子を使用する共通テーブル式と組み合わせることで、結果セットの「ページ」を作成することができます。たとえば、結果1〜10を含むページ1、結果11〜20を含むページ2、結果21〜30を含むページ3などがあります。

WITH data
AS
(
    SELECT ROW_NUMBER() OVER (ORDER BY name) AS row_id,
        object_id,
        name, 
        type,
        create_date
    FROM sys.objects
)
SELECT *
FROM data
WHERE row_id BETWEEN 41 AND 50

注意: WHERE句でROW_NUMBERを使用することはできません。

SELECT object_id,
    name,
    type,
    create_date
FROM sys.objects
WHERE ROW_NUMBER() OVER (ORDER BY name) BETWEEN 41 AND 50

これはより便利ですが、この場合SQL Serverは次のエラーを返します。

メッセージ4108、レベル15、状態1、行6

ウィンドウ関数は、SELECT句またはORDER BY句にしか現れません。

OFFSET FETCHによるページネーション

SQL Server 2012

OFFSET FETCH句は、より簡潔な方法でページネーションを実装します。これにより、N1行( OFFSET指定)をスキップし、次のN2行( FETCH指定)を戻すことができます。

SELECT *
FROM sys.objects
ORDER BY object_id
OFFSET 40 ROWS FETCH NEXT 10 ROWS ONLY

決定論的な結果を得るためには、 ORDER BY句が必要です。

内部クエリを使用したページネーション

以前のバージョンのSQL Serverでは、ページ内の行を返すために、開発者はTOPキーワードと組み合わせてダブルソートを使用する必要がありました。

 SELECT TOP 10 *
 FROM
 (
    SELECT
    TOP 50 object_id,
        name,
        type,
        create_date
    FROM sys.objects
    ORDER BY name ASC
) AS data
ORDER BY name DESC

内部クエリは、 name順に並べられた最初の50行を返します。次に、外側のクエリは、これらの50行の順序を逆にして、上位10行を選択します(これらは、反転前の最後の10行になります)。

さまざまなバージョンのSQL Serverでのページング

SQL Server 2012/2014


DECLARE @RowsPerPage INT = 10, @PageNumber INT = 4
SELECT OrderId, ProductId
FROM OrderDetail
ORDER BY OrderId
OFFSET (@PageNumber - 1) * @RowsPerPage ROWS
FETCH NEXT @RowsPerPage ROWS ONLY

SQL Server 2005/2008 / R2


DECLARE @RowsPerPage INT = 10, @PageNumber INT = 4
SELECT OrderId, ProductId
FROM (
    SELECT OrderId, ProductId, ROW_NUMBER() OVER (ORDER BY OrderId) AS RowNum
    FROM OrderDetail) AS OD
WHERE OD.RowNum BETWEEN ((@PageNumber - 1 ) * @RowsPerPage) + 1
AND @RowsPerPage * @PageNumber

SQL Server 2000


DECLARE @RowsPerPage INT = 10, @PageNumber INT = 4
SELECT OrderId, ProductId
FROM (SELECT TOP (@RowsPerPage) OrderId, ProductId
        FROM (SELECT TOP ((@PageNumber)*@RowsPerPage) OrderId, ProductId
                FROM OrderDetail
                ORDER BY OrderId) AS OD
    ORDER BY OrderId DESC) AS OD2
ORDER BY OrderId ASC

ORDER BY OFFSETとFETCH NEXTを使用したSQL Server 2012/2014

次の10行を取得するには、このクエリを実行します。

SELECT * FROM TableName ORDER BY id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;

使用時に考慮すべき重要ポイント:

  • ORDER BYは、 OFFSET句とFETCH句を使用するために必須です。
  • FETCH OFFSET句が必須です。 ORDER BY ... FETCHは使用できません。
  • 同じ問合せ式でTOPOFFSETおよびFETCHと組み合わせることはできません。


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow