私はmysqlでこのクエリを持っています:
select * from table1 LIMIT 10,20
Microsoft SQLでこれを行うにはどうすればよいですか?
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
ぎこちないが、それは動作します。
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です。この種の巧妙な回避策を実行する必要はありません。
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に変更された場合、返される結果セットは期待どおりではありません。
これは、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;
SELECT *
FROM (
SELECT TOP 20
t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn
FROM table1 t
ORDER BY
field1
) t
WHERE rn > 10
これは、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 の詳細については、リンクをご覧ください。
構文的には、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
これは、私が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の行にあるデータに制限されます。
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;
これは、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
しようとする必要があります。以下のクエリでは、グループ化、並べ替え、行のスキップ、行の制限を確認できます。
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
これをMSSQLExpress 2017で使用することをお勧めします。
SELECT * FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as [Count], * FROM table1
) as a
WHERE [Count] BETWEEN 10 and 20;
-列[カウント]を指定し、何かを注文せずにすべての行に一意のカウントを割り当ててから、制限を指定できる場所を再度選択します。
SQLにはLIMITキーワードは存在しません。限られた数の行のみが必要な場合は、LIMITに類似したTOPキーワードを使用する必要があります。
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から