在SQL Server中限制10..20

时间:2009-06-09 19:15:30

标签: sql sql-server pagination limit

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

SELECT * FROM table LIMIT 10,20

SELECT * FROM table LIMIT 10 OFFSET 10

但使用SQL Server

唯一的solution I found看起来有点矫枉过正:

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

我也是found

SELECT TOP 10 * FROM stuff; 

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

我还有另一种方法吗?

另外,只是好奇,有没有理由为什么SQL Server不支持LIMIT函数或类似的东西?我不想吝啬,但这听起来像DBMS需要的东西......如果确实如此,那么我很抱歉这么无知!我在过去的5年里一直在使用MySQL和SQL +,所以...

15 个答案:

答案 0 :(得分:122)

对于SQL Server 2012 + you can use

SELECT  *
FROM     sys.databases
ORDER BY name 
OFFSET  5 ROWS 
FETCH NEXT 5 ROWS ONLY 

答案 1 :(得分:99)

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

其他品牌的数据库可能具有相似的功能(例如Microsoft SQL Server中的TOP),但这些功能并不总是相同。

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

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

另一种解决方案是使用TOP获取第一个计数 + 偏移量行,然后使用API​​搜索第一个偏移量行。

另见:

答案 2 :(得分:34)

如您所见,这是首选的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

答案 3 :(得分:10)

如果您对Martin Smith's answer使用SQL Server 2012+投票并使用OFFSET的{​​{1}}和FETCH 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

以及在MS SQL 2012之前我在TSQL中所做的最佳表现方式。


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

答案 4 :(得分:6)

不幸的是,ROW_NUMBER()是您能做的最好的事情。它实际上更正确,因为limittop子句的结果在没有特定顺序的情况下实际上没有意义。但这仍然是一件痛苦的事。

更新:Sql Server 2012通过OFFSET和FETCH关键字添加了类似limit的功能。

答案 5 :(得分:5)

这个怎么样?

SET ROWCOUNT 10 

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

它为您提供前20行的最后10行。一个缺点是订单是相反的,但至少它很容易记住。

答案 6 :(得分:2)

SELECT TOP 10 *
FROM TABLE
WHERE IDCOLUMN NOT IN (SELECT TOP 10 IDCOLUMN FROM TABLE)

应该给出记录11-20。 如果增加以获得更多页面可能效率不高,并且不确定它如何受到排序的影响。 可能必须在两个WHERE语句中指定它。

答案 7 :(得分:1)

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

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

答案 8 :(得分:1)

仅适用于大多数数据库引擎的记录解决方案,但可能效率最低:

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

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

答案 9 :(得分: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

答案 10 :(得分: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行。

答案 11 :(得分: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}

侧面的注释,对动态数据进行分页会导致奇怪/意外的结果。

答案 12 :(得分: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;

答案 13 :(得分:0)

使用所有SQL服务器: ;使用tbl as(SELECT ROW_NUMBER()over(order by(select 1))as RowIndex,* from table) 从tbl中选择前10 *,其中RowIndex&gt; = 10

答案 14 :(得分:-3)

 SELECT * FROM users WHERE Id Between 15 and 25

它将在15到25之间打印,就像MYSQl中的限制一样