そのため、Webサイトにページングを実装したいレコードの数を返す関数があります。これを実現するには、SQL Server 2012のOffset/Fetch Nextを使用することをお勧めしました。私たちのウェブサイトには、レコードの総数とその時点でどのページにいるかをリストするエリアがあります。
以前は、レコードセット全体を取得し、プログラムでページングを構築できました。しかし、FETCH NEXT X ROWS ONLYでSQLの方法を使用すると、X行しか返されないため、合計レコードセットが何であるか、および最小ページと最大ページを計算する方法がわかりません。これを行うことができる唯一の方法は、関数を2回呼び出して、最初の行で行数をカウントしてから、2番目の行をFETCH NEXTで実行することです。クエリを2回実行しなくてもよい方法はありますか?パフォーマンスを遅くするのではなく、スピードを上げようとしています。
COUNT(*) OVER()
を使用できます...ここに_sys.all_objects
_を使用した簡単な例を示します。
_DECLARE
@PageSize INT = 10,
@PageNum INT = 1;
SELECT
name, object_id,
overall_count = COUNT(*) OVER()
FROM sys.all_objects
ORDER BY name
OFFSET (@PageNum-1)*@PageSize ROWS
FETCH NEXT @PageSize ROWS ONLY;
_
ただし、これは小さなデータセット用に予約する必要があります。大規模なセットでは、パフォーマンスがひどくなります。 より良い代替策については、このPaul Whiteの記事を参照 、インデックス付きビューの維持(結果がフィルター処理されていないか、WHERE
句を事前に知っている場合のみ機能します)およびROW_NUMBER()
トリック。
COUNT()OVER()メソッドを使用してパフォーマンスの問題が発生しました(10レコードを返すのに40秒かかり、その後問題がなかったため、サーバーであるかどうかはわかりません)。この手法は、COUNT()OVER()を使用せずにすべての条件下で機能し、同じことを実現します。
DECLARE
@PageSize INT = 10,
@PageNum INT = 1;
WITH TempResult AS(
SELECT ID, Name
FROM Table
), TempCount AS (
SELECT COUNT(*) AS MaxRows FROM TempResult
)
SELECT *
FROM TempResult, TempCount
ORDER BY TempResult.Name
OFFSET (@PageNum-1)*@PageSize ROWS
FETCH NEXT @PageSize ROWS ONLY
ジェームスモーバーグの答え に基づく:
SQL Server 2012がなく、OFFSETを使用できない場合、これはRow_Number()
を使用する代替手段です
DECLARE
@PageNumEnd INT = 10,
@PageNum INT = 1;
WITH TempResult AS(
SELECT ID, NAME
FROM Tabla
), TempCount AS (
SELECT COUNT(*) AS MaxRows FROM TempResult
)
select *
from
(
SELECT
ROW_NUMBER() OVER ( ORDER BY PolizaId DESC) AS 'NumeroRenglon',
MaxRows,
ID,
Name
FROM TempResult, TempCount
)resultados
WHERE NumeroRenglon >= @PageNum
AND NumeroRenglon <= @PageNumEnd
ORDER BY NumeroRenglon