How to implement LIMIT with Microsoft SQL Server?
我有这个查询与mysql:
1 | SELECT * FROM table1 LIMIT 10,20 |
如何使用Microsoft sql执行此操作?
启动SQL SERVER 2005,可以执行此操作...
1 2 3 4 5 6 7 8 9 10 11 | 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及以下版本...
1 | SELECT TOP 10 * FROM (SELECT TOP 20 FROM TABLE ORDER BY Id) ORDER BY Id DESC |
笨拙,但可以使用。
1 | SELECT TOP 10 * FROM TABLE WHERE id NOT IN (SELECT TOP 10 id FROM TABLE ORDER BY id) FROM TABLE ORDER BY id |
IMO忽略了MSSQL的LIMIT子句。您不必执行这种笨拙的解决方法。
从SQL SERVER 2012开始,可以使用OFFSET FETCH子句:
1 2 3 4 5 6 7 8 | 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/zh-CN/library/ms188385(v=sql.110).aspx
如果订购依据不是唯一的,这可能无法正常工作。
如果查询被修改为ORDER BY OrderDate,则返回的结果集与预期的不同。
这几乎是我十月份提出的一个问题的重复:
在Microsoft SQL Server 2000中模拟MySQL LIMIT子句
如果您使用的是Microsoft SQL Server 2000,则没有好的解决方案。大多数人不得不诉诸使用
如果使用的是Microsoft SQL Server 2005或更高版本,则具有
1 2 3 4 5 6 | 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的答案所示。
这就是我如何限制MS SQL Server 2012中的结果:
1 2 3 4 | SELECT * FROM table1 ORDER BY columnName OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY |
注意:
解释代码行
以前面的示例为基础:如果表1有40条记录,并且您从第10行开始提取并获取NEXT集10(
这意味着,上面的代码将从表1中的记录开始,从第10行开始,到第20行结束。因此,提取第10-20行。
查看链接以获取有关OFFSET的更多信息
1 2 3 4 5 6 7 8 9 | SELECT * FROM ( SELECT TOP 20 t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn FROM table1 t ORDER BY field1 ) t WHERE rn > 10 |
从语法上来说,MySQL LIMIT查询是这样的:
1 | SELECT * FROM TABLE LIMIT OFFSET, ROW_COUNT |
可以将其翻译成Microsoft SQL Server,例如
1 2 3 4 5 6 | SELECT * FROM ( SELECT TOP #{OFFSET+ROW_COUNT} *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum FROM TABLE ) a WHERE rnum > OFFSET |
现在您的查询
1 2 3 4 5 6 | SELECT * FROM ( SELECT TOP 30 *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum FROM table1 ) a WHERE rnum > 10 |
这是我尝试避免使用MS Server的原因之一...但无论如何。有时您只是没有选择(是!我必须使用过时的版本!)。
我的建议是创建一个虚拟表:
从:
1 | SELECT * FROM TABLE |
至:
1 2 | CREATE VIEW v_table AS SELECT ROW_NUMBER() OVER (ORDER BY table_key) AS ROW,* FROM TABLE |
然后只需查询:
1 | SELECT * FROM v_table WHERE ROW BETWEEN 10 AND 20 |
如果添加或删除字段,"行"将自动更新。
此选项的主要问题是ORDER BY是固定的。因此,如果您想要不同的顺序,则必须创建另一个视图。
更新
这种方法还有另一个问题:如果尝试过滤数据,它将无法按预期工作。例如,如果您这样做:
1 | SELECT * FROM v_table WHERE FIELD = 'test' AND ROW BETWEEN 10 AND 20 |
WHERE限制为位于10到20之间的行中的那些数据(而不是搜索整个数据集并限制输出)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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 2 3 4 5 | 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 |
这是一种多步骤方法,将在SQL2000中起作用。
1 2 3 4 5 6 | -- 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 |
better use this in MSSQLExpress 2017.
1 2 3 4 5 | SELECT * FROM ( SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [COUNT], * FROM table1 ) AS a WHERE [COUNT] BETWEEN 10 AND 20; |
-赋予列[Count]并为每一行分配唯一的计数而无需排序,然后再次选择可以提供限制的位置。::)
在SQL中,不存在LIMIT关键字。如果只需要有限的行数,则应使用类似于LIMIT的TOP关键字。
如果您的ID是唯一标识符类型,或者表中的ID未排序,则必须在下面进行操作。
1 2 3 | SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS RowNumber,* FROM table1) a WHERE a.RowNumber BETWEEN 2 AND 5 |
该代码将是
1 | SELECT * FROM LIMIT 2,5 |
如果我没记错(自从使用SQL Server以来已经有一段时间了),您也许可以使用类似这样的命令:(2005年及以上)
1 2 3 4 5 | SELECT * ,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum] FROM SomeTable WHERE RowNum BETWEEN 10 AND 20 |
1 | SELECT TOP 10 * FROM TABLE; |
是相同的
1 | SELECT * FROM TABLE LIMIT 0,10; |
这是一篇有关在MsSQL中实现Limit的文章。它是一本不错的书,特别是注释。