如何使用 SQLServer 实现 LIMIT?

我在 MySQL 中有这样一个查询:

select * from table1 LIMIT 10,20

如何使用 SQLServer 进行此操作?

427030 次浏览
SELECT TOP 10 * FROM table;

SELECT * FROM table LIMIT 0,10;

这里有一篇关于在 MsSQL 中实现 Limit 的文章,读起来很不错,尤其是注释。

从 SQLSERVER2005开始,您可以这样做..。

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

如果我没有记错的话(我已经有一段时间没有使用 SQL Server 了) ,你也许可以使用这样的东西: (2005年及以上)

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

这几乎是我10月份问过的一个问题的重复: 在2000年的 Microsoft SQL Server 中仿效 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 的 回答所示。

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

这是一种在 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

语法上,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
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;

这是我尽量避免使用 MS 服务器的原因之一... ... 但无论如何。有时候你就是没有选择(耶!我不得不使用一个过时的版本! !).

我的建议是创建一个虚拟表:

来自:

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

如果添加或删除字段,“ row”将自动更新。

这个选项的主要问题是 ORDERBY 是固定的。因此,如果想要不同的顺序,就必须创建另一个视图。

更新

这种方法还有另一个问题: 如果您尝试过滤数据,那么它不会像预期的那样工作。例如:

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

WHERE 变得仅限于那些位于10到20行之间的数据(而不是搜索整个数据集并限制输出)。

从 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

如果顺序 by 不是唯一的,则此命令可能无法正确工作。

如果查询被修改为 ORDERBYOrderDate,则返回的结果集不如预期。

这就是我在 MSSQLServer2012中限制结果的方法:

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

注意: OFFSET只能与 ORDER BY一起使用或与 ORDER BY串联使用。

解释代码行 OFFSET xx ROWS FETCH NEXT yy ROW ONLY

xx是您希望从表中开始提取的记录/行号,即: 如果表1中有40条记录,上面的代码将从第10行开始提取。

yy是要从表中提取的记录/行数。

在前一个示例的基础上构建: 如果表1有40条记录,并且您开始从第10行获取下一组10(yy)。 这意味着,上面的代码将从表1中提取从第10行开始到20行结束的记录。因此,拉行10-20。

点击链接了解更多关于 偏移量的信息

在 SQL 中不存在 LIMIT 关键字。如果您只需要有限的行数,那么您应该使用类似于 LIMIT 的 TOP 关键字。

必须尝试。在下面的查询中,您可以看到按组排列、按顺序排列、跳过行和限制行。

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

如果你的 ID 是唯一标识符类型,或者表格中的 ID 没有排序,你必须这样做。

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



密码是

select * from limit 2,5

最好在 MSSQLExpress2017中使用它。

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

--给一个列[ Count ] ,并在不排序的情况下为每一行分配一个唯一的计数,然后重新选择可以提供限制的位置。.:)

其中一个可能的方法得到的结果如下,希望这将有所帮助。

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

小菜一碟

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 是强制性的