このクエリでページング(スキップ/テイク)機能を実装する


138

私はSQLでカスタムページングを実装する方法について少し理解しようとしています。たとえば、このような記事を読んでいます。

次のクエリがありますが、これは完全に機能します。しかし、私はこれでページングを実装したいと思います。

SELECT TOP x PostId FROM ( SELECT PostId, MAX (Datemade) as LastDate
 from dbForumEntry 
 group by PostId ) SubQueryAlias
 order by LastDate desc

何が欲しい

フォーラムの投稿と関連エントリがあります。最近追加されたエントリを含む投稿を取得したいので、最近議論された投稿を選択できます。

ここで、「トップ10」の代わりに「最近アクティブなトップ10〜20の投稿」を取得できるようにしたいと考えています。

私は何を試しましたか

私はROW関数を記事の1つとして実装しようとしましたが、実際にはうまくいきませんでした。

それを実装する方法はありますか?

回答:


288

SQL Server 2012のそれは非常に非常に簡単です

SELECT col1, col2, ...
 FROM ...
 WHERE ... 
 ORDER BY -- this is a MUST there must be ORDER BY statement
-- the paging comes here
OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

ORDER BYをスキップしたい場合は、

SELECT col1, col2, ...
  ...
 ORDER BY CURRENT_TIMESTAMP
OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

(私はむしろそれをハックとしてマークしたいのですが、それは例えばNHibernateによって使用されています。賢明にピックアップされた列をORDER BYとして使用することをお勧めします)

質問に答えるには:

--SQL SERVER 2012
SELECT PostId FROM 
        ( SELECT PostId, MAX (Datemade) as LastDate
            from dbForumEntry 
            group by PostId 
        ) SubQueryAlias
 order by LastDate desc
OFFSET 10 ROWS -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

新しいキーワードoffsetfetch next(SQL規格に従うだけで)が導入されました。

しかし、私は、あなたが使用していないことを、推測するSQL Server 2012のを右、?以前のバージョンでは、少し(少し)難しいです。ここでは、すべてのSQLサーバーのバージョンの比較および実施例は次のとおりです。ここで

したがって、これはSQL Server 2008で機能する可能性があります

-- SQL SERVER 2008
DECLARE @Start INT
DECLARE @End INT
SELECT @Start = 10,@End = 20;


;WITH PostCTE AS 
 ( SELECT PostId, MAX (Datemade) as LastDate
   ,ROW_NUMBER() OVER (ORDER BY PostId) AS RowNumber
   from dbForumEntry 
   group by PostId 
 )
SELECT PostId, LastDate
FROM PostCTE
WHERE RowNumber > @Start AND RowNumber <= @End
ORDER BY PostId

どうもありがとう!それは本当に良い答えです!SQL 2008についての質問のみ。ORDER BYはWHEREの前に発生させたいので、現在はサブセットをソートしますが、セット全体から何かを選択したいのですが...何かアイデアはありますか?:)もう一度、ありがとう
Lars Holdgaard

2
私があなたを正しく理解しているのなら、LastDateで並べ替えたいと思いませんか?次に、OVER()句を次のように変更できます:ROW_NUMBER()OVER(ORDER BY MAX(Datemade)desc)。最後のORDER BY PostIdを削除します。これで、CTEは必要に応じて「早く」ソートされるはずです。正しい?
RadimKöhler12年

1
この助けてくれてありがとう、2012年のサンプルに関するメモ、order byは必須です、order by句なしでこれを試してみましたが、MSDN構文を調べて、order byが必須であることを学ぶまで、エラー「不正な構文」は何が悪いのかわからなかった。
Esen

最初の行は1または0ですか?が0でWHERE RowNumber >= @Start AND RowNumber < @End1000の場合、WHERE は最初の1000行を取得する必要@Startがあり@Endますか?
CWSpear 2015

1
ありがとうございました
マフィイ2018年




-1

次のように、ページ付けにネストされたクエリを使用できます。

CustomerId主キーである4行から8行へのページング。

SELECT Top 5 * FROM Customers
WHERE Country='Germany' AND CustomerId Not in (SELECT Top 3 CustomerID FROM Customers
WHERE Country='Germany' order by city) 
order by city;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.