ROW_NUMBER
 
 
•  
   DECLARE @
    page
    INT, @
    size 
    INT 
   SELECT @
    page
    = 
    1, @
    size
    = 
    10 
   
WITH 
    cte
    AS(
    
   SELECT 
    TOP(@
    page
    * @
    size)
    
   D.
    DeliveryOrder_ID,
    
   D.
    CarrierCode,
    
   D.
    ProgressCode,
    
   ROW_NUMBER() 
     OVER(
    ORDER 
     BY 
    D.
    DeliveryOrder_ID)
    AS 
    Seq,
    
   COUNT(
    *)
    OVER(
    PARTITION
    BY 
    '') 
    AS 
     Total 
   FROM 
    DeliveryOrder
    AS 
    D 
   ORDER 
    BY
    D.
    DeliveryOrder_ID
    ASC 
   
    )
    
   SELECT 
    *
    FROM 
    cte 
   WHERE 
    seq
    BETWEEN(@
    page
    - 
    1 ) 
    * @
    size 
    +
    1 
     AND @
    page
    * @
    size 
   ORDER 
    BY
    seq;
    
   GO
 • 2012 使用OFFSET
• DECLARE @
    page
    INT, @
    size 
    INTSELECT @
    page
    = 
    1, @
    size
    = 
    10
SELECT*FROM 
    DeliveryOrder
    AS 
    DORDER 
    BY
    D.
    DeliveryOrder_ID
    ASCOFFSET(@
    page
    -
    1) 
    * @
    size 
     ROWSFETCH 
    NEXT @
    size
    ROWS 
    ONLY;
   GO
SET 
    STATISTICS
    IO 
    OFF;
   SET 
    STATISTICS
    TIME 
    OFF;
   GO

限制和局限

ORDER BY 子句中的列数没有限制;但是,在 ORDER BY 子句中指定的列的总大小不能超过 8,060 个字节。

无法在 ORDER BY 子句中使用 ntext、text、image、geography、geometry 和 xml

在 order_by_expression 出现在排名函数中时,无法指定整数或常量。 有关详细信息,请参阅 OVER 子句 (Transact-SQL)

如果已在 FROM 子句中指定了表名的别名,则在 ORDER BY 子句中只能使用该别名来限定其列。

如果 SELECT 语句包含以下子句或运算符之一,则必须在选择列表中定义在 ORDER BY 子句中指定的列名和别名:

  • UNION 运算符

  • EXCEPT 运算符

  • INTERSECT 运算符

  • SELECT DISTINCT

此外,当语句包含 UNION、EXCEPT 或 INTERSECT 运算符时,必须在第一个(左侧)查询的选择列表中指定列名或列别名。

在使用 UNION、EXCEPT 或 INTERSECT 运算符的查询中,只允许在语句末尾使用 ORDER BY。 只有在顶级查询而不是子查询中指定了 UNION、EXCEPT 和 INTERSECT 时,此限制才适用。 请参阅后面的“示例”一节。

除非还指定了 TOP 子句或 OFFSET 和 FETCH 子句,否则,视图、内联函数、派生表和子查询中的 ORDER BY 子句无效。 在这些对象中使用 ORDER BY 时,该子句仅用于确定由 TOP 子句或 OFFSET 和 FETCH 子句返回的行。 ORDER BY 不保证在查询这些构造时得到有序结果,除非在查询本身中也指定了 ORDER BY。

索引视图或使用 CHECK OPTION 子句定义的视图中不支持 OFFSET 和 FETCH。

可以在允许 TOP 和 ORDER BY 的任何查询中使用 OFFSET 和 FETCH,但具有以下限制:

  • OVER 子句不支持 OFFSET 和 FETCH。

  • 无法在 INSERT、UPDATE、MERGE 和 DELETE 语句中直接指定 OFFSET 和 FETCH,但可以在这些语句定义的子查询中指定 OFFSET 和 FETCH。 例如,在 INSERT INTO SELECT 语句中,可以在 SELECT 语句中指定 OFFSET 和 FETCH。

  • 在使用 UNION、EXCEPT 或 INTERSECT 运算符的查询中,只能在指定查询结果顺序的最终查询中指定 OFFSET 和 FETCH。

  • 不能在同一查询表达式(相同查询作用域中)中将 TOP 与 OFFSET 和 FETCH 结合使用。

使用 OFFSET 和 FETCH 限制返回的行数



建议您使用 OFFSET 和 FETCH 子句而不是 TOP 子句实现查询分页解决方案,并限制发送到客户端应用程序的行数。

如果将 OFFSET 和 FETCH 作为分页解决方案,则需要为返回到客户端应用程序的每“页”数据运行一次查询。 例如,要以 10 行为增量返回查询结果,您必须执行一次查询以返回 1-10 行,然后再次运行查询以返回 11- 20 行,依此类推。 每个查询都是独立的,不会以任何方式与其他查询相关联。这意味着,与使用执行一次查询并在服务器上保持状态的游标不同,将由客户端应用程序负责跟踪状态。 若要使用 OFFSET 和 FETCH 在查询请求之间获得稳定的结果,必须满足以下条件:

  1. 查询使用的基础数据不能发生变化。 即,不会更新查询处理的行,也不会在单个事务中使用快照或可序列化事务隔离执行查询中的所有页面请求。 有关这些事务隔离级别的详细信息,请参阅 SET TRANSACTION ISOLATION LEVEL (Transact-SQL)

  2. ORDER BY 子句包含保证是唯一的列或列组合。

请参阅本主题后面的“示例”部分中的“在单个事务中运行多个查询”示例。

如果一致的执行计划在分页解决方案中至关重要,应考虑使用 OFFSET 和 FETCH 参数的 OPTIMIZE FOR 查询提示。 请参阅本主题后面的“示例”部分中的“指定 OFFSET 和 FETCH 值的表达式”。 有关 OPTIMZE FOR 的详细信息,请参阅查询提示 (Transact-SQL)