web-dev-qa-db-ja.com

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

私はmysqlでこのクエリを持っています:

select * from table1 LIMIT 10,20

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

118
Bigballs

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
113
Leon Tayson

ぎこちないが、それは動作します。

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です。この種の巧妙な回避策を実行する必要はありません。

53
ceejayoz

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に変更された場合、返される結果セットは期待どおりではありません。

29
user4047259

これは、10月に私が尋ねた質問とほとんど同じです。 Microsoft SQL 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の answer に示すように、これを 共通テーブル式 として記述することもできます。

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

これは、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のNEXTセット(yy)を取得した場合。つまり、上記のコードは、表1から行10で始まり20で終わるレコードをプルします。したがって、行10〜20をプルします。

OFFSET の詳細については、リンクをご覧ください。

12
Jeremy

構文的には、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 
8
user1134160

これは、私が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が修正されることです。したがって、別の順序が必要な場合は、別のビューを作成する必要があります。

UPDATE

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

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

WHEREは、データセット全体を検索して出力を制限する代わりに、10〜20の行にあるデータに制限されます。

2
lepe
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;
1
Julian Moreno

これは、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
souLTower

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

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
1
M Danish

これを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
user1308314

SQLにはLIMITキーワードは存在しません。限られた数の行のみが必要な場合は、LIMITに類似したTOPキーワードを使用する必要があります。

0
Mitul Panchal

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
user3244012