SQL ServerでLIMITを実装する方法は?


130

MySQLでこのクエリを使用します。

select * from table1 LIMIT 10,20

SQL Serverでこれを行うにはどうすればよいですか?



13
この質問が最初に尋ねられたので、他の質問は重複ではないでしょうか?
Tab Alleman 2015年

回答:


127

SQL SERVER 2005以降では、これを行うことができます...

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 10 AND 20;

または2000以下のバージョンではこのようなもの...

SELECT TOP 10 * FROM (SELECT TOP 20 FROM Table ORDER BY Id) ORDER BY Id DESC

6
たとえばテーブルに14行ある場合、2番目のクエリは失敗します。行5〜14が表示されますが、行11〜14が必要です。一般に、行の総数がその「ページ」サイズの倍数でない限り、結果の最後の「ページ」で失敗します。
ビルカーウィン

147
そのような単純なことは、MSによってさらに困難にする必要があります!
マーティン

SQL Server Management Studio 2017で機能したのは次のとおりです。SELECT* FROM [dbo]。<insert tableName here> WHERE @@ ROWCOUNT BETWEEN <insert min here> and <insert max here>
Artorias2718

ただ素晴らしい、それはMS SQL Server 2017 selectステートメントの魅力のように機能します
PatsonLeaner

58

不格好ですが、うまくいきます。

SELECT TOP 10 * FROM table WHERE id NOT IN (SELECT TOP 10 id FROM table ORDER BY id) FROM table ORDER BY id

MSSQLがLIMIT句を省略しているのは犯罪です、IMO。この種の無骨な回避策を実行する必要はありません。


これを回避するための別の提案がありますか?
Bigballs 2009年

前回MSSQLに対処する必要があったときに、私は多くのグーグル操作を行いましたが、これが私が見つけた最良のソリューションでした。快適ではありませんが、動作します。
ceejayoz 2009年

このソリューションは、結果セットに一意の列が含まれている場合にのみ機能します。クエリのLIMITを模倣する一般的なソリューションではありません。
ビルカーウィン

1
私は今、似たような難問にいます...しかし、私の場合、私はうんざりしています...いわゆる「エキスパート」dbaが、一意のキーがテーブルに不要であると決定した場合、それはさらに犯罪的です...すべてのテーブル...外部キーと制約の主題を持ち出さないでください!
Andrew Rollings

これの問題は、WHERE句がうまく処理されないことです。一時テーブルを試してみます。機能しないためです。
厄介なペースト

37

SQL SERVER 2012以降、OFFSET FETCH句を使用できます。

USE AdventureWorks;
GO
SELECT SalesOrderID, OrderDate
FROM Sales.SalesOrderHeader 
ORDER BY SalesOrderID
    OFFSET 10 ROWS
    FETCH NEXT 10 ROWS ONLY;
GO

http://msdn.microsoft.com/en-us/library/ms188385(v=sql.110).aspx

順序が一意でない場合、これは正しく機能しない可能性があります。

クエリがORDER BY OrderDateに変更された場合、返される結果セットは期待どおりではありません。


「with」を使用すると、クエリを完了するのに必要な時間が半分になります。@ Leon Taysonの回答を参照してください。私はそれを遅くするためにマイクロソフトが何をしたか分かりません。
isHuman

1
なぜこれは受け入れられない答えですか?私たちは大声で叫ぶために2018年にいます!
スキッパー2018年

1
@スキッパー右。受け入れられたものはまだ機能します。更新を反映するためにこれに賛成投票しましょう。
kronn

18

これは、10月に尋ねた質問とほぼ同じ です。MicrosoftSQL Server 2000でのMySQL LIMIT句のエミュレート

Microsoft SQL Server 2000を使用している場合、適切な解決策はありません。ほとんどの人は、IDENTITY主キーを持つ一時テーブルにクエリの結果を取り込むことに頼らなければなりません。次に、BETWEEN条件を使用して主キー列に対してクエリを実行します。

Microsoft SQL Server 2005以降を使用している場合はROW_NUMBER()関数があるため、同じ結果を得ることができますが、一時テーブルを回避できます。

SELECT t1.*
FROM (
    SELECT ROW_NUMBER OVER(ORDER BY id) AS row, t1.*
    FROM ( ...original SQL query... ) t1
) t2
WHERE t2.row BETWEEN @offset+1 AND @offset+@count;

@Leon Taysonの回答に示されているように、これを共通テーブル式として記述することもできます


ROW_NUMBER()OVER(ORDER BY)は、ANSI SQL:2003で有効であるためにポイントを取得しますが、SQL Server以外のDBMSでのサポートは非​​常に不安定です。そして、それはもちろんかなり不格好です...
bobince 2009年

@bobince:Oracle、Microsoft SQL Server 2005、IBM DB2、PostgreSQL 8.4のすべてがウィンドウ関数をサポートしていることがわかります。これは、SQL市場の大部分をカバーしています。MySQL、SQLite、または上記の古いバージョンのDBを使用している場合のみ、サポートが不安定になります。
ビルカーウィン、2010年

16

これは、MS SQL Server 2012で結果を制限する方法です。

SELECT * 
FROM table1
ORDER BY columnName
  OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY

注:OFFSETと組み合わせて、またはと組み合わせてのみ使用できORDER BYます。

コード行を説明するには OFFSET xx ROWS FETCH NEXT yy ROW ONLY

xxは、テーブルでプルを開始するレコード/行番号です。つまり、テーブル1に40レコードがある場合、上記のコードは行10からプルを開始します。

これyyは、テーブルから取得するレコード/行の数です。

前の例を基にするには:テーブル1に40レコードがあり、行10からプルを開始して、次の10のセット(yy)を取得したとします。つまり、上記のコードは、行1から20で終わるテーブル1からレコードをプルします。したがって、行10から20をプルします。

オフセットの詳細については、リンクを確認してください


12
SELECT  *
FROM    (
        SELECT  TOP 20
                t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn
        FROM    table1 t
        ORDER BY
                field1
        ) t
WHERE   rn > 10

さて、チェックしたところ、ORDER BY句にインデックス付きの列がある場合、SQL ServerはROW_NUMBER()条件で停止するのに十分スマートであることがわかりました。
Quassnoi 2009年

9

構文的には、MySQL LIMITクエリは次のようなものです。

SELECT * FROM table LIMIT OFFSET, ROW_COUNT

これは、Microsoft SQL Serverに変換できます。

SELECT * FROM 
(
    SELECT TOP #{OFFSET+ROW_COUNT} *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table
) a
WHERE rnum > OFFSET

これで、クエリselect * from table1 LIMIT 10,20は次のようになります。

SELECT * FROM 
(
    SELECT TOP 30 *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table1
) a
WHERE rnum > 10 

2

これが、MSサーバーの使用を避けようとする理由の1つですが、とにかく。時々、あなたにはオプションがないだけです(yei!と私は古いバージョンを使わなければなりません!!)。

私の提案は仮想テーブルを作成することです:

から:

SELECT * FROM table

に:

CREATE VIEW v_table AS    
    SELECT ROW_NUMBER() OVER (ORDER BY table_key) AS row,* FROM table

次に、クエリを実行します。

SELECT * FROM v_table WHERE row BETWEEN 10 AND 20

フィールドが追加または削除されると、「行」は自動的に更新されます。

このオプションの主な問題は、ORDER BYが修正されていることです。したがって、別の順序が必要な場合は、別のビューを作成する必要があります。

更新

このアプローチには別の問題があります。データをフィルタリングしようとすると、期待どおりに機能しません。たとえば、次の場合:

SELECT * FROM v_table WHERE field = 'test' AND row BETWEEN 10 AND 20

WHEREは、(データセット全体を検索して出力を制限するのではなく)10から20までの行にあるデータに制限されます。


1

これは、SQL2000で機能する複数ステップのアプローチです。

-- Create a temp table to hold the data
CREATE TABLE #foo(rowID int identity(1, 1), myOtherColumns)

INSERT INTO #foo (myColumns) SELECT myData order By MyCriteria

Select * FROM #foo where rowID > 10

1
SELECT 
    * 
FROM 
    (
        SELECT 
            top 20              -- ($a) number of records to show
            * 
        FROM
            (
                SELECT 
                    top 29      -- ($b) last record position
                    * 
                FROM 
                    table       -- replace this for table name (i.e. "Customer")
                ORDER BY 
                    2 ASC
            ) AS tbl1 
        ORDER BY 
            2 DESC
    ) AS tbl2 
ORDER BY 
    2 ASC;

-- Examples:

-- Show 5 records from position 5:
-- $a = 5;
-- $b = (5 + 5) - 1
-- $b = 9;

-- Show 10 records from position 4:
-- $a = 10;
-- $b = (10 + 4) - 1
-- $b = 13;

-- To calculate $b:
-- $b = ($a + position) - 1

-- For the present exercise we need to:
-- Show 20 records from position 10:
-- $a = 20;
-- $b = (20 + 10) - 1
-- $b = 29;

私にとって素晴らしい解決策でした。
Tyde 2014

1

しようとする必要があります。以下のクエリでは、グループ化、並べ替え、行のスキップ、および行の制限を確認できます。

select emp_no , sum(salary_amount) from emp_salary
Group by emp_no 
ORDER BY emp_no 
OFFSET 5 ROWS       -- Skip first 5 
FETCH NEXT 10 ROWS ONLY; -- limit to retrieve next 10 row after skiping rows

0
SELECT TOP 10 * FROM table;

と同じです

SELECT * FROM table LIMIT 0,10;

ここでMsSQLがで制限を実装についての記事です。その素敵な読み取り、特別にコメントが。


1
ありがとう、でも10から20までのレコードが欲しいのですが、それを行う方法はありますか?
Bigballs 2009年

5
...この答えは、原点の質問にない応答を行いますが、私のような人は、最初のN個の結果を取得し、などのGoogleを経由してここに来た方法を知る必要がある場合に便利です
brianlmerritt

0

SQLでは、LIMITキーワードは存在しません。限られた数の行だけが必要な場合は、LIMITと同様のTOPキーワードを使用する必要があります。


0

IDが一意の識別子タイプであるか、テーブル内のIDがソートされていない場合は、以下のようにする必要があります。

select * from
(select ROW_NUMBER() OVER (ORDER BY (select 0)) AS RowNumber,* from table1) a
where a.RowNumber between 2 and 5



コードは

選択*制限2,5から

0

これはMSSQLExpress 2017でより適切に使用します。

SELECT * FROM
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as [Count], * FROM table1
) as a
WHERE [Count] BETWEEN 10 and 20;

-列[カウント]を指定し、何かを注文せずにすべての行に一意のカウントを割り当てて、制限を提供できる場所で再度選択します。


0

以下のように結果を得る可能な方法の1つは、これが役立つことを願っています。

declare @start int
declare @end int
SET @start = '5000';  -- 0 , 5000 ,
SET @end = '10000'; -- 5001, 10001
SELECT * FROM ( 
  SELECT TABLE_NAME,TABLE_TYPE, ROW_NUMBER() OVER (ORDER BY TABLE_NAME) as row FROM information_schema.tables
 ) a WHERE a.row > @start and a.row <= @end

0

簡単な方法

MYSQL:

SELECT 'filds' FROM 'table' WHERE 'where' LIMIT 'offset','per_page'

MSSQL:

SELECT 'filds' FROM 'table' WHERE 'where' ORDER BY 'any' OFFSET 'offset' 
ROWS FETCH NEXT 'per_page' ROWS ONLY

ORDER BYは必須です


-2

私が正しく覚えている場合は(SQL Serverを使用してからしばらく経っています)、次のようなものを使用できる場合があります(2005以降)。

SELECT
    *
   ,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum]
FROM SomeTable
WHERE RowNum BETWEEN 10 AND 20

SQL Server 2012:メッセージ207、レベル16、状態1、行5無効な列名 'RowNum'。
e-info128 2013年

ステートメントのどこかにタイプミスがあるようです。RowNumは、式に割り当てる名前です。ソースに問題を投稿すると、コミュニティが役立ちます
Kris

これは有効な構文ではありません。WHERE同じレベルSELECT句で定義されたエイリアスで参照することはできません。
ypercubeᵀᴹ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.