我对MySQL有以下查询:
select * from table1 LIMIT 10,20
如何使用SQL Server执行此操作?
我对MySQL有以下查询:
select * from table1 LIMIT 10,20
如何使用SQL Server执行此操作?
Answers:
启动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
IMO忽略MSSQL的LIMIT子句。您不必执行这种笨拙的解决方法。
从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/zh-CN/library/ms188385(v=sql.110).aspx
当订购依据不是唯一时,这可能无法正常工作。
如果查询被修改为ORDER BY OrderDate,则返回的结果集与预期的不同。
这几乎是我十月份提出的一个问题的重复: 在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;
这是我如何限制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
是你要开始从下表中,即拉动记录/行数:如果有40条记录在表1中,上面的代码将开始从第10行拉。
的 yy
是你想从表中拉记录/行数。
以前面的示例为基础:如果表1有40条记录,并且您从第10行开始提取并获取NEXT集10(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 Server的原因之一...但无论如何。有时您只是没有选择(是!我必须使用过时的版本!)。
我的建议是创建一个虚拟表:
从:
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之间的行中的那些数据(而不是搜索整个数据集并限制输出)。
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;
SELECT TOP 10 * FROM table;
是相同的
SELECT * FROM table LIMIT 0,10;
这是一篇有关在MsSQL中实现Limit的文章,非常好阅读,特别是注释。
在SQL中,不存在LIMIT关键字。如果只需要有限的行数,则应使用类似于LIMIT的TOP关键字。
如下获得结果的一种可能方法,希望这会有所帮助。
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
如果我没记错(自从使用SQL Server以来已经有一段时间了),您也许可以使用类似这样的命令:(2005年及以上)
SELECT
*
,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum]
FROM SomeTable
WHERE RowNum BETWEEN 10 AND 20
WHERE
同一level SELECT
子句中定义的别名。