En SQL Server, el ROW_NUMBER()
La función le permite numerar la salida de un conjunto de resultados. Devuelve el número secuencial de cada fila, empezando por 1.
Si especifica particiones para el conjunto de resultados, cada partición hace que la numeración comience de nuevo (es decir, la numeración comenzará en 1 para la primera fila de cada partición).
Sintaxis
La sintaxis es así:
ROW_NUMBER ( ) OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )
PARTITION BY value_expression
es opcional. Divide el conjunto de resultados producido por FROM
cláusula en particiones a las que se aplica la función. valor_expresión especifica la columna por la que se particiona el conjunto de resultados. Si la PARTITION BY
no se especifica la cláusula, todas las filas del conjunto de resultados de la consulta se tratan como un solo grupo.
ROW_NUMBER
dentro de una partición especificada.
Tenga en cuenta que OVER
normalmente acepta una cláusula
Ejemplo 1:uso básico
Aquí hay un ejemplo básico que muestra cómo funciona esta función:
SELECT ROW_NUMBER() OVER (ORDER BY AlbumId ASC) 'Row', AlbumId, AlbumName FROM Albums;
Resultado:
+-------+-----------+--------------------------+ | Row | AlbumId | AlbumName | |-------+-----------+--------------------------| | 1 | 1 | Powerslave | | 2 | 2 | Powerage | | 3 | 3 | Singing Down the Lane | | 4 | 4 | Ziltoid the Omniscient | | 5 | 5 | Casualties of Cool | | 6 | 6 | Epicloud | | 7 | 7 | Somewhere in Time | | 8 | 8 | Piece of Mind | | 9 | 9 | Killers | | 10 | 10 | No Prayer for the Dying | | 11 | 11 | No Sound Without Silence | | 12 | 12 | Big Swing Face | | 13 | 13 | Blue Night | | 14 | 14 | Eternity | | 15 | 15 | Scandinavia | | 16 | 16 | Long Lost Suitcase | | 17 | 17 | Praise and Blame | | 18 | 18 | Along Came Jones | | 19 | 19 | All Night Wrong | | 20 | 20 | The Sixteen Men of Tain | | 21 | 21 | Yo Wassup | | 22 | 22 | Busted | +-------+-----------+--------------------------+
En este caso podemos ver que los números de fila se alinean perfectamente con los valores en el AlbumId
columna. Esto es pura coincidencia. Esto sucede porque el AlbumId
columna está usando un valor incremental que comienza en 1, que también es lo que ROW_NUMBER()
usos.
La numeración de las filas se correlaciona con el AlbumId
columna en la medida en que está ordenada por esa columna. Pero eso no significa que los valores deban ser los mismos.
Ejemplo 2:agregar una cláusula WHERE
Agregando un WHERE
cláusula demostrará lo que quiero decir.
SELECT ROW_NUMBER() OVER (ORDER BY AlbumId ASC) 'Row', AlbumId, AlbumName FROM Albums WHERE AlbumId > 15;
Resultado:
+-------+-----------+-------------------------+ | Row | AlbumId | AlbumName | |-------+-----------+-------------------------| | 1 | 16 | Long Lost Suitcase | | 2 | 17 | Praise and Blame | | 3 | 18 | Along Came Jones | | 4 | 19 | All Night Wrong | | 5 | 20 | The Sixteen Men of Tain | | 6 | 21 | Yo Wassup | | 7 | 22 | Busted | +-------+-----------+-------------------------+
Ejemplo 3:cambia el orden
Ordenar en orden descendente en lugar de ascendente también demuestra este concepto.
SELECT ROW_NUMBER() OVER (ORDER BY AlbumId DESC) 'Row', AlbumId, AlbumName FROM Albums;
Resultado:
+-------+-----------+--------------------------+ | Row | AlbumId | AlbumName | |-------+-----------+--------------------------| | 1 | 22 | Busted | | 2 | 21 | Yo Wassup | | 3 | 20 | The Sixteen Men of Tain | | 4 | 19 | All Night Wrong | | 5 | 18 | Along Came Jones | | 6 | 17 | Praise and Blame | | 7 | 16 | Long Lost Suitcase | | 8 | 15 | Scandinavia | | 9 | 14 | Eternity | | 10 | 13 | Blue Night | | 11 | 12 | Big Swing Face | | 12 | 11 | No Sound Without Silence | | 13 | 10 | No Prayer for the Dying | | 14 | 9 | Killers | | 15 | 8 | Piece of Mind | | 16 | 7 | Somewhere in Time | | 17 | 6 | Epicloud | | 18 | 5 | Casualties of Cool | | 19 | 4 | Ziltoid the Omniscient | | 20 | 3 | Singing Down the Lane | | 21 | 2 | Powerage | | 22 | 1 | Powerslave | +-------+-----------+--------------------------+
Ejemplo 4:ordenar por una columna diferente
Y ya que estamos en eso, ordenemos por AlbumName
columna en su lugar.
SELECT ROW_NUMBER() OVER (ORDER BY AlbumName ASC) 'Row', AlbumId, AlbumName FROM Albums;
Resultado:
+-------+-----------+--------------------------+ | Row | AlbumId | AlbumName | |-------+-----------+--------------------------| | 1 | 19 | All Night Wrong | | 2 | 18 | Along Came Jones | | 3 | 12 | Big Swing Face | | 4 | 13 | Blue Night | | 5 | 22 | Busted | | 6 | 5 | Casualties of Cool | | 7 | 6 | Epicloud | | 8 | 14 | Eternity | | 9 | 9 | Killers | | 10 | 16 | Long Lost Suitcase | | 11 | 10 | No Prayer for the Dying | | 12 | 11 | No Sound Without Silence | | 13 | 8 | Piece of Mind | | 14 | 2 | Powerage | | 15 | 1 | Powerslave | | 16 | 17 | Praise and Blame | | 17 | 15 | Scandinavia | | 18 | 3 | Singing Down the Lane | | 19 | 7 | Somewhere in Time | | 20 | 20 | The Sixteen Men of Tain | | 21 | 21 | Yo Wassup | | 22 | 4 | Ziltoid the Omniscient | +-------+-----------+--------------------------+
Ejemplo 5:Particiones
Como se mencionó, también puede dividir los resultados en particiones. Cuando hace esto, la numeración comienza de nuevo en 1 para cada nueva partición.
Ejemplo:
SELECT Genre, ROW_NUMBER() OVER (PARTITION BY Genre ORDER BY AlbumId ASC) 'Row', AlbumId, AlbumName FROM Albums INNER JOIN Genres ON Albums.GenreId = Genres.GenreId;
Resultado:
+---------+-------+-----------+--------------------------+ | Genre | Row | AlbumId | AlbumName | |---------+-------+-----------+--------------------------| | Country | 1 | 3 | Singing Down the Lane | | Country | 2 | 21 | Yo Wassup | | Country | 3 | 22 | Busted | | Jazz | 1 | 12 | Big Swing Face | | Jazz | 2 | 19 | All Night Wrong | | Jazz | 3 | 20 | The Sixteen Men of Tain | | Pop | 1 | 11 | No Sound Without Silence | | Pop | 2 | 13 | Blue Night | | Pop | 3 | 14 | Eternity | | Pop | 4 | 15 | Scandinavia | | Pop | 5 | 16 | Long Lost Suitcase | | Pop | 6 | 17 | Praise and Blame | | Pop | 7 | 18 | Along Came Jones | | Rock | 1 | 1 | Powerslave | | Rock | 2 | 2 | Powerage | | Rock | 3 | 4 | Ziltoid the Omniscient | | Rock | 4 | 5 | Casualties of Cool | | Rock | 5 | 6 | Epicloud | | Rock | 6 | 7 | Somewhere in Time | | Rock | 7 | 8 | Piece of Mind | | Rock | 8 | 9 | Killers | | Rock | 9 | 10 | No Prayer for the Dying | +---------+-------+-----------+--------------------------+
Una vez más podemos ver que el ROW_NUMBER
y el AlbumId
las columnas están completamente descorrelacionadas.
En este caso divido por el Genre
columna. Esto hace que la numeración comience de nuevo en 1 para cada género.