Para empezar, algo a lo largo de las líneas de:
SELECT my_first_column, my_second_column,
ROW_NUMBER() OVER (ORDER BY my_order_column) AS Row_Counter
FROM my_table
Sin embargo, es importante tener en cuenta que la construcción ROW_NUMBER() OVER (ORDER BY ...)
sólo determina los valores de Row_Counter
, que no garantiza el orden de los resultados.
A menos que el SELECT
tenga una cláusula explícita ORDER BY
, los resultados podrían devolverse en cualquier orden, dependiendo de cómo SQL Server decida optimizar la consulta. (. See this article for more info)
La única manera de garantizar que los resultados serán siempre ser devueltos en Row_Counter
fin es aplicar exactamente el mismo orden tanto a la SELECT
y la ROW_NUMBER()
:
SELECT my_first_column, my_second_column,
ROW_NUMBER() OVER (ORDER BY my_order_column) AS Row_Counter
FROM my_table
ORDER BY my_order_column -- exact copy of the ordering used for Row_Counter
El patrón anterior siempre devolverá resultados en el orden correcto y funciona bien para consultas simples, pero ¿qué tal una consulta "arbitrariamente compleja" con quizás docenas de expresiones en la cláusula ORDER BY
? En esas situaciones prefiero algo como esto en su lugar:
SELECT t.*
FROM
(
SELECT my_first_column, my_second_column,
ROW_NUMBER() OVER (ORDER BY ...) AS Row_Counter -- complex ordering
FROM my_table
) AS t
ORDER BY t.Row_Counter
Usando una consulta anidada significa que no hay necesidad de duplicar la complicada ORDER BY
cláusula, lo que significa menos desorden y un mantenimiento más fácil. El exterior ORDER BY t.Row_Counter
también hace que la intención de la consulta sea mucho más clara para sus compañeros desarrolladores.
¿Por qué la consulta anidada? Con mi prueba rápida de ROW_NUMBER(), la consulta resultante terminó ordenada por el valor del contador de filas de todos modos. – andynormancx
La consulta anidada anterior no es necesaria, pero ocasionalmente puede ser útil escribir "SELECT t. * FROM (...) as t WHERE t.Row_Counter BEWEEN 20 and 30" como una forma eficiente de enviar datos a la página. – Juliet
La consulta anidada * es * obligatoria si desea garantizar que el conjunto de resultados siempre se devolverá en el orden de Fila_Counter para consultas "arbitrariamente complejas". (Consulte http://blogs.msdn.com/queryoptteam/archive/2006/05/02/588731.aspx para obtener más información.) – LukeH