HiveBrain v1.2.0
Get Started
← Back to all entries
debugsqlModerate

SQL Server Error, "Invalid usage of the option FIRST in the FETCH statement."

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
errorthestatementsqlfetchoptionusagefirstserverinvalid

Problem

From 2012 onward the SQL Server docs show they support OFFSET..FETCH which I'm trying to use instead of a LIMIT.

The following works fine in PostgreSQL to sample a result set,

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


However, with SQL Server, I get

Msg 153, Level 15, State 2, Line 4
Invalid usage of the option FIRST in the FETCH statement.


What's going on here? Does SQL Server support the standardized OFFSET .. FETCH?

Solution

SQL Server has implemented the OFFSET and FETCH clauses as part of the ORDER BY clause, as pointed by the other answers and documented in their documentation.

The SQL standard on the other side, has both of these clauses as independent:

 ::=
[  ] 
[  ] [  ] [  ]


If someone wants this feature implemented in full compliance with the standard, they can always make a request to the SQL Server team, through the Connect channel. In fact, MS has commented - in a different request about offset and fetch:

Connect item: SQL Denali: add total rows counter to SELECT statement - by Alexey Rokhin

Answer: Posted by Microsoft on 24/11/2010 at 11:34

The requirement that OFFSET/FETCH requires ORDER BY is a restriction in this release. In the ANSI SQL standard (SQL:2011) where the new OFFSET/FETCH clauses are proposed, ORDER BY is optional. The restriction in SQL Server has to do with limitation in our parser technology that cannot handle the optional syntax without making OFFSET a reserved keyword. We may remove it in the future.

Now with respect to ...

Until then, if one wants to use OFFSET and FETCH without a specific ORDER BY, a workaround is to add a "do nothing" order by clause. Example:

SELECT 
...
ORDER BY (SELECT NULL)
OFFSET 0 ROWS
FETCH NEXT 1 ROWS ONLY;

Code Snippets

<query expression> ::=
[ <with clause> ] <query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
SELECT 
...
ORDER BY (SELECT NULL)
OFFSET 0 ROWS
FETCH NEXT 1 ROWS ONLY;

Context

StackExchange Database Administrators Q#193783, answer score: 17

Revisions (0)

No revisions yet.