web-dev-qa-db-ja.com

SQL ServerのLIMIT 10..20

私は次のようなことをしようとしています:

SELECT * FROM table LIMIT 10,20

または

SELECT * FROM table LIMIT 10 OFFSET 10

ただし、SQL Serverを使用する

唯一の 私が見つけた解決策 はやり過ぎのように見える:

SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases 
 ) a WHERE row > 5 and row <= 10

私も found

SELECT TOP 10 * FROM stuff; 

...しかし、開始制限を指定できないため、それは私がやりたいことではありません。

私がそれを行う別の方法はありますか?

また、奇妙なことに、SQL ServerがLIMIT関数などをサポートしていない理由はありますか?私は意地悪になりたくありませんが、それはDBMSが必要とするもののように本当に聞こえます...もしそうなら、私はとても無知であることを残念に思います!私は過去5年間、MySQLとSQL +を扱ってきました...

154
marcgg

LIMIT句は標準SQLの一部ではありません。 MySQL、PostgreSQL、SQLiteによるSQLのベンダー拡張としてサポートされています。

他のブランドのデータベースにも同様の機能がある場合があります(Microsoft SQL ServerのTOPなど)が、これらは常に同じように機能するとは限りません。

TOP句を模倣するためにMicrosoft SQL ServerでLIMITを使用するのは困難です。うまくいかない場合があります。

ROW_NUMBER()を使用して示したソリューションは、Microsoft SQL Server 2005以降で使用できます。これは、現時点ではクエリの一部としてのみ機能する最適なソリューションです。

別の解決策は、TOPを使用して最初のcount+offset行をフェッチすることです、APIを使用して最初のoffset行を検索します。

こちらもご覧ください:

100
Bill Karwin

SQL Server 2012 + 使用可能 の場合。

SELECT  *
FROM     sys.databases
ORDER BY name 
OFFSET  5 ROWS 
FETCH NEXT 5 ROWS ONLY 
122
Martin Smith

あなたが見つけたように、これは好ましいSQLサーバーの方法です:

SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases 
 ) a WHERE a.row > 5 and a.row <= 10
34
KM.

SQL Server 2012+を使用して Martin Smithの答え に投票し、FETCH NEXTOFFSETおよびORDER BY拡張を使用している場合、

以前のバージョンにこだわるほど不幸な場合は、次のようなことができます。

WITH Rows AS
(
    SELECT
              ROW_NUMBER() OVER (ORDER BY [dbo].[SomeColumn]) [Row]
            , *
        FROM
              [dbo].[SomeTable]
)
SELECT TOP 10
          *
     FROM
         Rows
    WHERE Row > 10

私はと機能的に同等であると信じています

SELECT * FROM SomeTable LIMIT 10 OFFSET 10 ORDER BY SomeColumn

そして、MS SQL 2012より前のTSQLでそれを行うことで私が知っている最高のパフォーマンスの方法。


行が非常に多い場合は、CTEの代わりに一時テーブルを使用するとパフォーマンスが向上する場合があります。

10
Jodrell

残念ながら、ROW_NUMBER()が最善です。 limit句またはtop句の結果は、特定の順序に関係なく、実際には意味を持たないため、実際にはより正確です。しかし、それでもやることは苦痛です。

更新:SQL Server 2012は、 OFFSETおよびFETCHキーワード を介してlimitのような機能を追加します。これは、非標準のMySql拡張機能であるLIMITとは対照的に、ANSI標準のアプローチです。

7
Joel Coehoorn

これはどう?

SET ROWCOUNT 10 

SELECT TOP 20 *
FROM sys.databases
ORDER BY database_id DESC

最初の20行の最後の10行が表示されます。 1つの欠点は、順序が逆になることですが、少なくとも覚えやすいです。

5
David Patrick
SELECT TOP 10 *
FROM TABLE
WHERE IDCOLUMN NOT IN (SELECT TOP 10 IDCOLUMN FROM TABLE)

11-20の記録を与える必要があります。インクリメントしてさらにページを取得する場合はおそらく効率的ではなく、順序によってどのような影響を受けるかはわかりません。両方のWHEREステートメントでこれを指定する必要がある場合があります。

2
Andy

最も効率的ではないかもしれませんが、ほとんどのデータベースエンジンで機能する記録的なソリューションのためだけに:

Select Top (ReturnCount) *
From (
    Select Top (SkipCount + ReturnCount) *
    From SourceTable
    Order By ReverseSortCondition
) ReverseSorted
Order By SortCondition

注:SkipCountが何であっても、最後のページにはReturnCount行が含まれます。しかし、多くの場合、それは良いことかもしれません。

1
Y.B.

良い方法は、プロシージャを作成することです:

create proc pagination (@startfrom int ,@endto int) as
SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name desc) as row FROM sys.databases 
 ) a WHERE a.row > @startfrom and a.row <= @endto

制限0,2のように////////////////ページネーション0,4を実行

1
Wahaj Latif

LIMITに相当するのはSET ROWCOUNTですが、一般的なページネーションが必要な場合は、次のようなクエリを作成することをお勧めします。

;WITH Results_CTE AS
(
    SELECT
        Col1, Col2, ...,
        ROW_NUMBER() OVER (ORDER BY SortCol1, SortCol2, ...) AS RowNum
    FROM Table
    WHERE <whatever>
)
SELECT *
FROM Results_CTE
WHERE RowNum >= @Offset
AND RowNum < @Offset + @Limit
1

すべてのSQLサーバーを使用:; with with tbl as(SELECT ROW_NUMBER()over(order by(select 1))as RowIndex、* from table)select top 10 * from tbl where RowIndex> = 10

0

MS SQL Serverのオンラインドキュメント( http://technet.Microsoft.com/en-us/library/ms186734.aspx )から、ここで、特定の行セット。 ROW_NUMBERにはOVERが必要ですが、好きなように注文できます:

WITH OrderedOrders AS
(
  SELECT SalesOrderID, OrderDate,
  ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
  FROM Sales.SalesOrderHeader 
) 
SELECT SalesOrderID, OrderDate, RowNumber  
FROM OrderedOrders 
WHERE RowNumber BETWEEN 50 AND 60;
0
Shannon WM

これまでのところ、このフォーマットは私のために働いているものです(ただし、最高のパフォーマンスではありません):

SELECT TOP {desired amount of rows} * 
FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY {order columns} asc)__row__ FROM {table})tmp
WHERE __row__ > {offset row count}

動的なデータのページ付けは、奇妙な/予期しない結果につながる可能性があります。

0
select * from (select id,name,ROW_NUMBER() OVER (ORDER BY id  asc) as row
from tableName1) tbl1
where tbl1.row>=10 and tbl1.row<=15

10〜15の行を印刷します。

0
sjith