SQL Server 错误,“FETCH 语句中选项 FIRST 的使用无效。”

Eva*_*oll 9 sql-server offset-fetch sql-server-2017

从 2012 年开始,SQL Server 文档显示他们支持OFFSET..FETCH我尝试使用的而不是LIMIT.

以下在 PostgreSQL 中可以很好地对结果集进行采样,

SELECT *
FROM ( VALUES (1),(2),(3) ) AS t(x)
OFFSET 0 ROWS
FETCH NEXT 1 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)

但是,使用 SQL Server,我得到

Msg 153, Level 15, State 2, Line 4
Invalid usage of the option FIRST in the FETCH statement.
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?SQL Server 是否支持标准化的OFFSET.. FETCH

ype*_*eᵀᴹ 17

SQL Server 已将OFFSETandFETCH子句作为子句的一部分实现ORDER BY,正如其他答案所指出的那样并记录在他们的文档中。

另一方面,SQL 标准将这两个子句作为独立的:

<query expression> ::=
[ <with clause> ] <query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
Run Code Online (Sandbox Code Playgroud)

如果有人希望在完全符合标准的情况下实现此功能,他们可以随时通过 Connect 通道向 SQL Server 团队提出请求。事实上,MS 已经评论过 - 在关于偏移和获取的不同请求中:

连接项目:SQL Denali:将总行数计数器添加到SELECT语句- 作者 Alexey Rokhin

答:Microsoft 于 24/11/2010 于 11:34 发表

要求OFFSET/FETCH需要ORDER BY在此版本的限制。OFFSET/FETCH提议新条款的 ANSI SQL 标准 (SQL:2011) 中,ORDER BY是可选的。SQL Server 中的限制与我们的解析器技术中的限制有关,即在不OFFSET使用保留关键字的情况下无法处理可选语法。我们将来可能会删除它。

现在关于...

在那之前,如果想要使用OFFSET并且FETCH没有特定的ORDER BY,一种解决方法是添加一个“什么都不做”的 order by 子句。例子:

SELECT 
...
ORDER BY (SELECT NULL)
OFFSET 0 ROWS
FETCH NEXT 1 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)


Sol*_*zky 10

正如关于..文档的最顶部所述OFFSETFETCH

OFFSET-FETCH 子句为您提供了一个选项,可以仅从结果集中获取一个窗口或结果页。OFFSET-FETCH 只能与 ORDER BY 子句一起使用。

...

ORDER BY 必须使用 OFFSET 和 FETCH 子句。

所以,

SELECT *
FROM ( VALUES (1),(2),(3) ) AS t(x)
ORDER BY t.[x]  /* <-- ADD ME TO BE HAPPY */
OFFSET 0 ROWS
FETCH NEXT 1 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)

不是所有的实用的简单LIMIT,如果这就是你要什么,你要坚持TOP


Dan*_*man 10

根据参考资料,该OFFSET子句是ORDER BYSQL Server 的一部分。您还需要ROWSOFFSET规范后添加关键字:

SELECT *
FROM ( VALUES (1),(2),(3) ) AS t(x)
ORDER BY x
OFFSET 0 ROWS
FETCH FIRST 1 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)