在SQL Server中限制10..20

mar*_*cgg 158 sql sql-server pagination limit

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

SELECT * FROM table LIMIT 10,20
Run Code Online (Sandbox Code Playgroud)

要么

SELECT * FROM table LIMIT 10 OFFSET 10
Run Code Online (Sandbox Code Playgroud)

但是使用SQL Server

我找到的唯一解决方案看起来像是矫枉过正:

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

我还发现:

SELECT TOP 10 * FROM stuff; 
Run Code Online (Sandbox Code Playgroud)

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

我还有另一种方法吗?

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

Mar*_*ith 132

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

SELECT  *
FROM     sys.databases
ORDER BY name 
OFFSET  5 ROWS 
FETCH NEXT 5 ROWS ONLY 
Run Code Online (Sandbox Code Playgroud)

  • 当您使用OFFSET 5 ROWS FETCH NEXT 5 ROWS时,SQl Server 2012需要指定ORDER BY,而当您使用LIMIT 5时,MySql和SQLite不需要ORDER BY (10认同)
  • @ qub1n - MySQL [不保证](http://stackoverflow.com/questions/6314879/does-limit-offset-length-require-order-by-for-pagination)在这种情况下你得到的行虽然. (4认同)
  • 你是否必须使用`offset`,或者你可以离开那条线(假设你不想要偏移)? (3认同)

Bil*_*win 101

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

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

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

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

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

也可以看看:


KM.*_*KM. 35

如您所见,这是首选的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
Run Code Online (Sandbox Code Playgroud)

  • @Lucas,你需要在`()`派生表之后添加一个别名,但是如果你忘记用它来引用列,它会让它去.我修好了...... (3认同)

Jod*_*ell 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
Run Code Online (Sandbox Code Playgroud)

我相信功能相当于

SELECT * FROM SomeTable LIMIT 10 OFFSET 10 ORDER BY SomeColumn
Run Code Online (Sandbox Code Playgroud)

在MS SQL 2012之前,我知道在TSQL中执行它的最佳表现方式.


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


Joe*_*orn 7

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

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

  • 因为没有order by子句就没有订单这样的东西.您可以获得服务器可用的任何记录顺序,并且可以从查询请求_change_查询请求. (3认同)
  • 如果您不想在ORDER BY子句中重复自己,请使用ROW_NUMBER()别名而不是原始列集. (3认同)
  • @Tomalak:就SQL Server而言,用于计算ROW_NUMBER()的顺序与结果集的排序完全无关.这就是你必须单独指定它们的原因. (2认同)

小智 5

这个怎么样?

SET ROWCOUNT 10 

SELECT TOP 20 *
FROM sys.databases
ORDER BY database_id DESC
Run Code Online (Sandbox Code Playgroud)

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

  • 如果表中只有14行怎么办?您将第14行减少到5,这与LIMIT 10 OFFSET 10返回的行不同(应该是第14行到第11行). (5认同)

小智 5

SELECT TOP 10 *
FROM TABLE
WHERE IDCOLUMN NOT IN (SELECT TOP 10 IDCOLUMN FROM TABLE)
Run Code Online (Sandbox Code Playgroud)

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