SQL Server的LIMIT和OFFSET的等价物?

Ear*_*rlz 161 sql sql-server limit offset

在PostgreSQL中,有一些LimitOffset关键字可以很容易地对结果集进行分页.

Sql Server的等效语法是什么?

Som*_*luk 215

现在,此功能在SQL Server 2012中变得非常简单.这从SQL Server 2012开始运行.

限制偏移量以在SQL Server中选择11到20行:

SELECT email FROM emailTable 
WHERE user_id=3
ORDER BY Id
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)
  • OFFSET:跳过的行数
  • NEXT:所需的下一行数

参考:https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-2017

  • 使用它时是否存在等效的"SQL_CALC_FOUND_ROWS"? (4认同)
  • 这应该是正确的答案 (3认同)

Aar*_*ght 135

相当于LIMITSET 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
Run Code Online (Sandbox Code Playgroud)

这里的优点是在您决定更改分页选项(或允许用户这样做)时,偏移和限制的参数化.

注:@Offset参数应使用基于1的索引为此而不是正常的从零开始的索引.

  • @JoelCoehoorn不老.我刚刚使用SLQ Server 2008分配给项目,过去只使用过mysql ... (30认同)
  • 现在老.Sql Server 2012及更高版本支持OFFSET/FETCH (21认同)
  • `ORDER BY子句在视图,内联函数,派生表,子查询和公用表表达式中无效,除非还指定了TOP或FOR XML.MSSQL2008 R2. (5认同)
  • @Aaronaught如果我的`Table`有200k记录,它将首先获取所有记录,然后应用限制?这个查询有效吗? (2认同)

jor*_*geu 23

select top {LIMIT HERE} * from (
      select *, ROW_NUMBER() over (order by {ORDER FIELD}) as r_n_n 
      from {YOUR TABLES} where {OTHER OPTIONAL FILTERS}
) xx where r_n_n >={OFFSET HERE}
Run Code Online (Sandbox Code Playgroud)

注意: 此解决方案仅适用于SQL Server 2005或更高版本,因为这是在ROW_NUMBER()实施时.

  • xx 只是一个表别名。如果你说“AS xx”可能会更清楚一些 (2认同)

Tom*_*m H 12

您可以在公用表表达式中使用ROW_NUMBER来实现此目的.

;WITH My_CTE AS
(
     SELECT
          col1,
          col2,
          ROW_NUMBER() OVER(ORDER BY col1) AS row_number
     FROM
          My_Table
     WHERE
          <<<whatever>>>
)
SELECT
     col1,
     col2
FROM
     My_CTE
WHERE
     row_number BETWEEN @start_row AND @end_row
Run Code Online (Sandbox Code Playgroud)


Hum*_*bir 11

特别是对于 SQL-SERVER,您可以通过许多不同的方式来实现这一点。对于给定的实际示例,我们在此处采用了 Customer 表。

示例 1:使用“SET ROWCOUNT”

SET ROWCOUNT 10
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Run Code Online (Sandbox Code Playgroud)

要返回所有行,请将 ROWCOUNT 设置为 0

SET ROWCOUNT 0  
SELECT CustomerID, CompanyName from Customers
    ORDER BY CompanyName
Run Code Online (Sandbox Code Playgroud)

示例 2:使用“ROW_NUMBER 和 OVER”

With Cust AS
( SELECT CustomerID, CompanyName,
ROW_NUMBER() OVER (order by CompanyName) as RowNumber 
FROM Customers )
select *
from Cust
Where RowNumber Between 0 and 10
Run Code Online (Sandbox Code Playgroud)

示例 3:使用“OFFSET 和 FETCH”,但使用此“ORDER BY”是强制性的

SELECT CustomerID, CompanyName FROM Customers
ORDER BY CompanyName
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

希望这对您有帮助。


小智 6

-- @RowsPerPage  can be a fixed number and @PageNumber number can be passed 
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 2

SELECT *

FROM MemberEmployeeData

ORDER BY EmployeeNumber

OFFSET @PageNumber*@RowsPerPage ROWS

FETCH NEXT 10 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)