Menu

Funciones de categoría 2/4, RANK()

agosto 25, 2013 - SQL Server

Continuando con nuestra serie de post de funciones de categoría en SQL Server seguimos con la función RANK(), esta función asigna un rango en un subconjunto de resultados dependiendo de la clausula de ordenamiento o del particionamiento del conjunto de datos. Al igual que la función ROW_NUMBER() fue implementada desde SQL Server 2005 .

Requisitos

Manos a la obra!

Su sintaxis general es la siguiente:

RANK() OVER([PARTITION BY Column] ORDER BY Column)

Para nuestro ejemplo utilizaremos la base de datos de AdventureWorks2012 y seleccionaremos de las tablas SalesOrderDetail, ProductSubcategory y ProductCategory:


SELECT
 Production.Product.Name,
 SUM(Sales.SalesOrderDetail.OrderQty) AS 'OrderQty',
 Production.ProductCategory.Name AS 'Category'
 FROM Production.ProductCategory
 INNER JOIN Production.ProductSubcategory
 ON ProductCategory.ProductCategoryID = ProductSubcategory.ProductCategoryID
 INNER JOIN Production.Product
 ON Product.ProductSubcategoryID = ProductSubcategory.ProductSubcategoryID
 INNER JOIN Sales.SalesOrderDetail
 ON Production.Product.ProductID = Sales.SalesOrderDetail.ProductID
 GROUP BY Production.Product.Name,
 Production.ProductCategory.Name
 ORDER BY Category

el resultado de la consulta es el siguiente:

image

Vemos un listado de productos con la sumatoria de ordenes y la categoría a la cual pertenecen. Vamos a sacar los productos que mayor cantidad de pedidos tienen:

SELECT
Production.Product.Name,
SUM(Sales.SalesOrderDetail.OrderQty) AS ‘OrderQty’,
Production.ProductCategory.Name AS ‘Category’,
RANK() OVER (ORDER BY SUM(Sales.SalesOrderDetail.OrderQty) DESC) AS ‘Rank’
FROM Production.ProductCategory
INNER JOIN Production.ProductSubcategory
ON ProductCategory.ProductCategoryID = ProductSubcategory.ProductCategoryID
INNER JOIN Production.Product
ON Product.ProductSubcategoryID = ProductSubcategory.ProductSubcategoryID
INNER JOIN Sales.SalesOrderDetail
ON Production.Product.ProductID = Sales.SalesOrderDetail.ProductID
GROUP BY Production.Product.Name,
Production.ProductCategory.Name
ORDER BY Rank

Este es el resultado que produce:

image

Observamos que el articulo que mas ordenes ha tenido es AWC Logo Cap. Aparentemente es igual a ROW_NUMBER(), sin embargo hasta este punto difiere en que cuando dos registros presentan cantidad en la columna del ORDER BY, se le asignara el mismo rango a ambos y para el siguiente registro tomara el próximo rango, por ejemplo, veamos el rango 101 de nuestra consulta:

image

Nótese que dos registros poseen la el rango 101 y el otro tiene 103, esto se da ya que tienen igual cantidad de ordenes.

PARTITION BY

La clausula PARTITION BY también puede ser utilizada en el OVER de la consulta para dividir el resultado en particiones y hacer que la función RANK() se aplique a cada partición:

SELECT
Production.Product.Name,
SUM(Sales.SalesOrderDetail.OrderQty) AS ‘OrderQty’,
Production.ProductCategory.Name AS ‘Category’,
RANK() OVER (PARTITION BY Production.ProductCategory.Name ORDER BY SUM(Sales.SalesOrderDetail.OrderQty) DESC) AS ‘Rank’
FROM Production.ProductCategory
INNER JOIN Production.ProductSubcategory
ON ProductCategory.ProductCategoryID = ProductSubcategory.ProductCategoryID
INNER JOIN Production.Product
ON Product.ProductSubcategoryID = ProductSubcategory.ProductSubcategoryID
INNER JOIN Sales.SalesOrderDetail
ON Production.Product.ProductID = Sales.SalesOrderDetail.ProductID
GROUP BY Production.Product.Name,
Production.ProductCategory.Name
ORDER BY Category

image

image

image

Vemos que el rango se asigna dependiendo de la columna que se especificó en el PARTITION BY, así obtenemos el rango de artículos con mas ordenes por categoría.

Conclusión

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.

Es todo por ahora, Happy coding Sonrisa

Deja un comentario

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