回答:
SQL Server 2005以降では、ROW_NUMBER関数を使用できます。例えば。
USE AdventureWorks;
GO
WITH OrderedOrders AS
(
SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
FROM Sales.SalesOrderHeader
)
SELECT *
FROM OrderedOrders
WHERE RowNumber BETWEEN 51 AND 60; --BETWEEN is inclusive
SQL Server 2012以降では、次の構文が追加されています。
SELECT *
FROM Sales.SalesOrderHeader
ORDER BY OrderDate
OFFSET (@Skip) ROWS FETCH NEXT (@Take) ROWS ONLY
LINQ to SQLは、ROW_NUMBERウィンドウ関数を使用してこれを行います。
SELECT a,b,c FROM
(SELECT a,b,c, ROW_NUMBER() OVER (ORDER BY ...) as row_number
FROM Table) t0
WHERE to.row_number BETWEEN 1000 and 1100;
これは機能しますが、ORDER BYからrow_numberを製造する必要があるため、クエリがサーバー側でソートされ、パフォーマンスの問題が発生する可能性があります。インデックスがORDER BY要件を満たすことができる場合でも、クエリは結果を返す前に1000行をカウントする必要があります。多くの場合、開発者はこれを忘れて、5 milの行テーブルにページ分割コントロールをスローし、最初のページが最後のページよりもはるかに速く返される理由を不思議に思っています...
それでも、ROW_NUMBER()を使用することは、ソートを回避することを確実にすれば、おそらく使いやすさと良好なパフォーマンスとの間の最良のバランスです(ORDER BY条件はインデックスで満たすことができます)。
これを試してください:
select * from [Table-Name] order by [Column-Name]
offset [Skip-Count] rows
FETCH NEXT [Take-Count] rows only
例:
select * from Personals order by Id
offset 10 rows --------->Skip 10
FETCH NEXT 15 rows only --------->Take 15
これを行う:
LINQ to SQLデータコンテキストで.Skip(1000).Take(100)を実行し、SQL出力を確認します。それはあなたが説明していることをするSQL文を生成します。
それはエレガントではありませんが、仕事を成し遂げます。
いいえ、ただし、MySQLのLIMIT句(Stack Overflowリンク)をエミュレートして同じ結果を得ることができます。