Menu

Funciones de categoría 1/4, ROW_NUMBER()

Agosto 19, 2013 - SQL Server

Dentro de las muchas funciones estadísticas que tiene SQL Server existen algunas muy poco utilizadas y conocidas de hecho, estoy hablando de las funciones de categoría, en esta ocasión veremos que hace la función ROW_NUMBER en una consulta SQL Server.

La función ROW_NUMBER() fue implementada en la versión 2005, y su resultado no es mas que hacer una numeración de cada fila seleccionada en función de su predicado de ordenamiento, decir se numeraran todas las filas seleccionadas comenzando en 1, teniendo en cuenta el criterio de ordenamiento.

Requisitos

Manos a la obra

La sintaxis general es la siguiente:

ROW NUMBER() OVER([PARTITION BY col] ORDER BY col)

Para nuestro ejemplo utilizaremos la base de datos de AdventureWorks2012 y seleccionaremos de las tablas Person, Sales y SalesTerritory el listado de las personas con su territorio y cuota de ventas:

SELECT
Person.Person.FirstName
, Person.Person.LastName
, Sales.SalesTerritory.Name AS 'Territory'
, Sales.SalesPerson.SalesQuota AS 'Sales'
, ROW_NUMBER() OVER(ORDER BY SalesQuota DESC) AS 'Row Number'
FROM Person.Person
INNER JOIN Sales.SalesPerson
ON Person.Person.BusinessEntityID = Sales.SalesPerson.BusinessEntityID
INNER JOIN Sales.SalesTerritory
ON Sales.SalesPerson.TerritoryID = Sales.SalesTerritory.TerritoryID

El cual produce el siguiente resultado: image En el ROW_NUMBER podemos notar la clausula OVER en la cual se especifica el criterio de ordenamiento que se tendrá en cuenta para asignar los números de cada fila.

PARTITION BY

NUMBER_ROW() también puede ser utilizada con la clausula PARTITION BY para dividir el resultado en particiones y que la función ROW_NUMBER se aplique a cada partición, reiniciando el conteo el cada una de estas, así por ejemplo podemos tener el ranking de vendedores con cuotas mas altas por territorio con la siguiente consulta:

SELECT
Person.Person.FirstName
, Person.Person.LastName
, Sales.SalesTerritory.Name AS 'Territory'
, Sales.SalesPerson.SalesQuota AS 'Sales'
, ROW_NUMBER() OVER (PARTITION BY Sales.SalesTerritory.Name ORDER BY SalesQuota) AS 'Row Number'
FROM Person.Person
INNER JOIN Sales.SalesPerson
ON Person.Person.BusinessEntityID = Sales.SalesPerson.BusinessEntityID
INNER JOIN Sales.SalesTerritory
ON Sales.SalesPerson.TerritoryID = Sales.SalesTerritory.TerritoryID

Este es el resultado que arroja: image He resaltado en colores 3 resultados que nos ayudan a comprender el particionamiento, el primer lugar vemos una partición: Australia con un único registro en morado, cuyo RowNumber es 1 puesto que es el único. Ahora veamos la partición verde, se refiere a Canada y el RowNumber se ha asignado consecutivamente por el campo de SalesQuota. Por última tenemos la partición roja Northwest, vemos como nuevamente el RowNumber se aplica de manera consecutiva para de acuerdo con el SalesQuota.

Conclusion

Las funciones de categoría se presentan como una solución para cuando necesitemos dar un peso o valor a un grupo de registros específicos en una consulta que puedan ser agrupados por una columna y ordenados por un criterio determinado. Ademas, la clausula ROW_NUMBER tiene mucho mas que dar en lo que hemos visto acá, por ejemplo podemos usarla con una variable tipo tabla o en un CTE para numerar las filas y recorrerlas con un WHILE en vez de utilizar un cursor, pero ese será otro post. Happy coding Sonrisa!

Un pensamiento sobre “Funciones de categoría 1/4, ROW_NUMBER()

  • Pingback: Paginado eficiente de grillas Parte 1/2 | EduardoOrtega.me()

  • Deja un comentario

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *