Error de SQL Server, "Uso no válido de la opción PRIMERO en la instrucción FETCH".

8

A partir de 2012, los documentos de SQL Server muestran que son compatibles con OFFSET..FETCHlo que estoy tratando de usar en lugar de a LIMIT.

Lo siguiente funciona bien en PostgreSQL para muestrear un conjunto de resultados,

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

Sin embargo, con SQL Server, obtengo

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

¿Que está pasando aqui? ¿SQL Server es compatible con el estándar OFFSET... FETCH?

Evan Carroll
fuente

Respuestas:

17

SQL Server ha implementado las cláusulas OFFSETy FETCHcomo parte de la ORDER BYcláusula, según lo señalado por las otras respuestas y documentado en su documentación.

El estándar SQL en el otro lado, tiene ambas cláusulas como independientes:

<query expression> ::=
[ <with clause> ] <query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]

Si alguien quiere que esta característica se implemente en total conformidad con el estándar, siempre puede hacer una solicitud al equipo de SQL Server, a través del canal Connect. De hecho, MS ha comentado, en una solicitud diferente sobre desplazamiento y recuperación:

Conecte el elemento: SQL Denali: agregue el contador total de filas a la SELECTdeclaración - por Alexey Rokhin

Respuesta: Publicado por Microsoft el 24/11/2010 a las 11:34

El requisito que OFFSET/FETCHrequiere ORDER BYes una restricción en esta versión. En el estándar ANSI SQL (SQL: 2011) donde OFFSET/FETCHse proponen las nuevas cláusulas, ORDER BYes opcional. La restricción en SQL Server tiene que ver con la limitación en nuestra tecnología de analizador que no puede manejar la sintaxis opcional sin hacer OFFSETuna palabra clave reservada. Podemos eliminarlo en el futuro.

Ahora con respecto a ...

Hasta entonces, si uno quiere usar OFFSETy FETCHsin un específico ORDER BY, una solución alternativa es agregar una orden de "no hacer nada" por cláusula. Ejemplo:

SELECT 
...
ORDER BY (SELECT NULL)
OFFSET 0 ROWS
FETCH NEXT 1 ROWS ONLY;
ypercubeᵀᴹ
fuente
10

Como se indica en la parte superior de la documentación sobre OFFSET...FETCH

La cláusula OFFSET-FETCH le brinda la opción de obtener solo una ventana o página de resultados del conjunto de resultados. OFFSET-FETCH solo se puede usar con la cláusula ORDER BY.

...

ORDER BY es obligatorio para usar la cláusula OFFSET y FETCH.

Entonces,

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;

No es tan práctico para un simple, LIMITsi eso es lo que buscas, querrás seguir TOP.

Solomon Rutzky
fuente
9

Según la referencia , la OFFSETcláusula forma parte de ORDER BYSQL Server. También deberá agregar la ROWSpalabra clave después de la OFFSETespecificación:

SELECT *
FROM ( VALUES (1),(2),(3) ) AS t(x)
ORDER BY x
OFFSET 0 ROWS
FETCH FIRST 1 ROWS ONLY;
Dan Guzman
fuente