174

我正在尝试做类似的事情:

SELECT * FROM table LIMIT 10,20

或者

SELECT * FROM table LIMIT 10 OFFSET 10

但使用 SQL Server

我发现的唯一解决方案看起来有点矫枉过正:

SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases 
 ) a WHERE row > 5 and row <= 10

我还发现

SELECT TOP 10 * FROM stuff; 

...但这不是我想做的,因为我无法指定起始限制。

我还有其他方法吗?

另外,只是好奇,是否有 SQL Server 不支持该LIMIT功能或类似功能的原因?我不想刻薄,但这听起来确实像是 DBMS 需要的东西……如果确实如此,那么我很抱歉我这么无知!在过去的 5 年里,我一直在使用 MySQL 和 SQL+,所以......

4

15 回答 15

140

对于 SQL Server 2012 + ,您可以使用.

SELECT  *
FROM     sys.databases
ORDER BY name 
OFFSET  5 ROWS 
FETCH NEXT 5 ROWS ONLY 
于 2012-02-11T16:46:58.667 回答
113

LIMIT子句不是标准 SQL 的一部分。MySQL、PostgreSQL 和 SQLite 支持它作为 SQL 的供应商扩展。

其他品牌的数据库可能具有类似的功能(例如TOP在 Microsoft SQL Server 中),但它们的工作方式并不总是相同。

TOP在 Microsoft SQL Server 中很难使用来模仿该LIMIT子句。在某些情况下它不起作用。

您展示的解决方案ROW_NUMBER()在 Microsoft SQL Server 2005 及更高版本中可用。这是仅作为查询的一部分工作的最佳解决方案(目前)。

另一种解决方案是使用TOP获取第一个count + offset行,然后使用 API 查找第一个offset行。

也可以看看:

于 2009-06-09T19:34:04.557 回答
36

如您所见,这是首选的 sql server 方法:

SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases 
 ) a WHERE a.row > 5 and a.row <= 10
于 2009-06-09T19:19:55.070 回答
10

如果您使用 SQL Server 2012+ 投票给Martin Smith 的答案并使用OFFSETFETCH NEXT扩展ORDER BY

如果你不幸被早期版本卡住了,你可以做这样的事情,

WITH Rows AS
(
    SELECT
              ROW_NUMBER() OVER (ORDER BY [dbo].[SomeColumn]) [Row]
            , *
        FROM
              [dbo].[SomeTable]
)
SELECT TOP 10
          *
     FROM
         Rows
    WHERE Row > 10

我相信在功能上等同于

SELECT * FROM SomeTable LIMIT 10 OFFSET 10 ORDER BY SomeColumn

在 MS SQL 2012 之前,我知道在 TSQL 中执行此操作的最佳执行方式。


如果有很多行,使用临时表而不是 CTE 可能会获得更好的性能。

于 2012-07-04T15:27:35.623 回答
9

这个怎么样?

SET ROWCOUNT 10 

SELECT TOP 20 *
FROM sys.databases
ORDER BY database_id DESC

它为您提供前 20 行中的最后 10 行。一个缺点是顺序颠倒了,但至少它很容易记住。

于 2009-06-09T19:33:40.580 回答
7

不幸的是,这ROW_NUMBER()是你能做的最好的。它实际上更正确,因为limitortop子句的结果在不考虑某些特定顺序的情况下并没有真正的意义。但是做起来还是很痛苦的。

更新: Sql Server 2012limit通过OFFSET 和 FETCH 关键字添加了类似功能。这是 ansi-standard 方法,而不是LIMIT非标准 MySql 扩展。

于 2009-06-09T19:19:18.080 回答
3
SELECT TOP 10 *
FROM TABLE
WHERE IDCOLUMN NOT IN (SELECT TOP 10 IDCOLUMN FROM TABLE)

应提供记录 11-20。如果递增以获取更多页面,并且不确定它可能如何受到排序的影响,则可能效率不高。可能必须在两个 WHERE 语句中指定这一点。

于 2011-01-10T15:46:46.990 回答
2

一个好方法是创建一个过程:

create proc pagination (@startfrom int ,@endto int) as
SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name desc) as row FROM sys.databases 
 ) a WHERE a.row > @startfrom and a.row <= @endto

就像限制 0,2 ////////////// 执行分页 0,4

于 2013-11-28T14:38:48.773 回答
1

仅适用于大多数数据库引擎的记录解决方案虽然可能不是最有效的:

Select Top (ReturnCount) *
From (
    Select Top (SkipCount + ReturnCount) *
    From SourceTable
    Order By ReverseSortCondition
) ReverseSorted
Order By SortCondition

请注意:无论 SkipCount 是什么,最后一页仍将包含 ReturnCount 行。但这在很多情况下可能是件好事。

于 2016-03-01T10:52:08.370 回答
1

LIMIT 的等价物是 SET ROWCOUNT,但如果您想要通用分页,最好编写如下查询:

;WITH Results_CTE AS
(
    SELECT
        Col1, Col2, ...,
        ROW_NUMBER() OVER (ORDER BY SortCol1, SortCol2, ...) AS RowNum
    FROM Table
    WHERE <whatever>
)
SELECT *
FROM Results_CTE
WHERE RowNum >= @Offset
AND RowNum < @Offset + @Limit
于 2016-04-12T09:21:47.147 回答
0
select * from (select id,name,ROW_NUMBER() OVER (ORDER BY id  asc) as row
from tableName1) tbl1
where tbl1.row>=10 and tbl1.row<=15

将打印从 10 到 15 的行。

于 2013-01-22T07:20:44.410 回答
0

到目前为止,这种格式对我有用(虽然不是最好的性能):

SELECT TOP {desired amount of rows} * 
FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY {order columns} asc)__row__ FROM {table})tmp
WHERE __row__ > {offset row count}

附带说明,对动态数据进行分页可能会导致奇怪/意外的结果。

于 2013-08-09T05:08:48.483 回答
0

从 MS SQL Server 在线文档 ( http://technet.microsoft.com/en-us/library/ms186734.aspx ) 中,这是我已经测试和工作的示例,用于检索一组特定的行。ROW_NUMBER 需要 OVER,但您可以按自己喜欢的顺序订购:

WITH OrderedOrders AS
(
  SELECT SalesOrderID, OrderDate,
  ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
  FROM Sales.SalesOrderHeader 
) 
SELECT SalesOrderID, OrderDate, RowNumber  
FROM OrderedOrders 
WHERE RowNumber BETWEEN 50 AND 60;
于 2013-10-08T20:15:00.280 回答
0

使用所有 SQL 服务器: ;with tbl as (SELECT ROW_NUMBER() over(order by(select 1)) as RowIndex,* from table) select top 10 * from tbl where RowIndex>=10

于 2015-01-10T06:06:57.530 回答
-3
 SELECT * FROM users WHERE Id Between 15 and 25

它将像 MYSQl 中的限制一样从 15 打印到 25

于 2015-06-05T10:55:33.810 回答