¿Se garantiza que SELECT ROW_NUMBER () devolverá los resultados ordenados por los números de fila generados?

10

Por ejemplo, considere la consulta SQL:

SELECT
   A.[Name],
   ROW_NUMBER() OVER(ORDER BY A.[Name] ASC)
FROM
   [FooTable] AS A

Aquí observo los resultados que se devuelven ordenados por A. [Nombre]. Si cambio la columna de clasificación definida en la función ROW_NUMBER a otra columna, nuevamente los resultados se ordenarán por esa columna.

Esperaba que se asignara el número de fila a las filas, pero no esperaba que las filas volvieran ordenadas por ese mismo criterio. ¿Es esto simplemente un efecto secundario de cómo se ejecuta la consulta (en mi caso en SQL Server 2008 R2) o se garantiza este comportamiento? (No pude encontrar ninguna referencia a dicha garantía).

Redcalx
fuente
10
Nunca hay ninguna garantía. Siempre. A menos que le indique a SQL Server cómo ordenar algo, es libre de devolver los datos en el orden que desee. Al omitir el pedido, le está diciendo a SQL Server que no le importa el pedido. Si desea una garantía, simplemente escriba la cláusula ORDER BY.
Aaron Bertrand
Hay una buena razón para preguntar, ya que la cláusula de orden en cuestión es muy compleja y, por lo tanto, la copia crea un lastre de mantenimiento de código y aumenta la probabilidad de defectos futuros. La otra alternativa es una refactorización menor que pensé que podría evitar si el estándar SQL definiera un orden de clasificación implícito. En cualquier caso, solo estaba interesado si había documentación formal que cubriera este punto.
redcalx
1
Entonces, ¿por qué no hacer esa pregunta?
Aaron Bertrand

Respuestas:

14

Si hiciste la pregunta, creo que realmente querías preguntar:

¿Cómo puedo ordenar ROW_NUMBER()sin repetir la ORDER BYexpresión compleja ?

Podríamos haberle dicho que creara un alias para la ROW_NUMBER()expresión y luego ordenara usando el alias:

SELECT
   A.[Name],
   rn = ROW_NUMBER() OVER (ORDER BY <complex expression>)
FROM
   dbo.[FooTable] AS A
ORDER BY rn;

Ahora solo tiene que cambiar la expresión en un lugar, y el orden resultante se basará en esa expresión sin tener que repetirla.

Aaron Bertrand
fuente
66
De hecho, repeating the complex ORDER BY expressionni siquiera garantiza que la salida saldrá por orden ROW_NUMBER (). A menos que las columnas en la cláusula ORDER BY formen una clave única.
孔夫子
22

Absolutamente no. Prueba:

SELECT
   A.[Name],
   ROW_NUMBER() OVER(ORDER BY A.[Name] ASC),
   ROW_NUMBER() OVER(ORDER BY A.[Name] DESC)
FROM
   [FooTable] AS A

La única forma de garantizar un pedido en SQL es solicitarlo, usarlo ORDER BYen el resultado mismo.

Remus Rusanu
fuente
OK Agregaré una calificación adicional: ¿se garantiza que los resultados se ordenarán si solo se especifica una cláusula ROW_NUMBER ()?
redcalx
22
La única forma de garantizar un pedido en SQL es solicitarlo
Remus Rusanu
0

En realidad, la pregunta (antigua) podría extenderse para incluir también la partición por parte, ya que parece haber un orden implícito primero por la partición por y luego el orden por parte (s)

Por lo tanto, no es tan simple como algunos han sugerido asignar el número de fila y usarlo para ordenar.

También necesitaríamos un sql anidado que extraiga la partición por cláusula (si no queremos simplemente repetirlo, por supuesto)

Empíricamente parece que obtenemos implícitamente la última línea de pedidos

Select
  <field-list>, 
  rn=Row_Number() over(partition by <PartionClause>) order by <OrderClause>
from ....
Order by <PartionClause> asc, rn asc

Pero lo que nos falta es alguna prueba o garantía de que siempre se mantenga.

(Si hay varias llamadas Row_Number () en juego, es la ÚLTIMA que parece dar el orden)

TAMBIÉN TENGA EN CUENTA que si agrega explícitamente el orden por el plan de ejecución, muestra claramente un paso de clasificación final, y ordenar un conjunto ya ordenado es el peor de los casos, por lo tanto, lleva mucho más tiempo con el orden por que sin

Eske Rahn
fuente
1
Esto realmente no responde la pregunta, y parece estar en desacuerdo tanto con la respuesta aceptada como con una respuesta altamente votada.
Erik Darling
Estoy de acuerdo en que el mío es más un comentario que una respuesta. Bueno, la respuesta aceptada no es realmente una respuesta, excepto que dice que es mejor no confiar en el orden, y esa fue la pregunta. El plan de ejecución puede ver que realmente hace una clasificación, y si agregamos un orden explícito, obtenemos una segunda clasificación. Pero eso NO es una prueba, es solo una parte del conocimiento empírico
Eske Rahn
(Por supuesto, solo hace el tipo si no hay un índice adecuado que pueda usar para acceder a la tabla, pero solo lo agregó para mostrar que generalmente no es gratis dar el pedido explícitamente)
Eske Rahn