sql >> Base de Datos >  >> RDS >> Sqlserver

Funciones de clasificación en SQL Server

Suponga que está diseñando una aplicación de base de datos de SQL Server para el director general de una empresa y tiene que mostrar el quinto empleado mejor pagado de la empresa.

¿Qué harías? Una solución es escribir una consulta como esta:

SELECT EmployeeName
FROM Employees
ORDER BY Salary DESC
OFFSET 4 ROWS
FETCH FIRST 1 ROWS ONLY;

La consulta anterior parece engorrosa, especialmente si tiene que clasificar a todos los empleados. En ese caso, una solución es hacer una lista de los empleados por orden descendente de salario y luego tomar el índice del empleado como rango. Sin embargo, las cosas se complican si varios empleados tienen el mismo salario. ¿Cómo los clasificaría?

Afortunadamente, SQL Server viene con funciones de clasificación integradas que se pueden usar para clasificar registros de varias maneras. En este artículo, presentaremos las funciones de clasificación del servidor SQL en detalle ilustrándolas con los ejemplos.

Hay cuatro tipos diferentes de función de clasificación en SQL Server:

  • Clasificación()
  • Dense_Rank()
  • Número de fila()
  • Ntile()

Es importante mencionar que todas las funciones de clasificación en el servidor SQL requieren la cláusula ORDER BY.

Antes de ver cada una de las funciones de clasificación en detalle, primero, creemos datos ficticios que usaremos en este artículo para explicar la función de clasificación. Ejecute el siguiente script:

CREATE DATABASE Showroom

Use Showroom
CREATE TABLE Car
(
CarId int identity(1,1) primary key,
Name varchar(100),
Make varchar(100),
Model int ,
Price int ,
Type varchar(20)
)

insert into Car( Name, Make, Model , Price, Type)
VALUES ('Corrolla','Toyota',2015, 20000,'Sedan'),
('Civic','Honda',2018, 25000,'Sedan'),
('Passo','Toyota',2012, 18000,'Hatchback'),
('Land Cruiser','Toyota',2017, 40000,'SUV'),
('Corrolla','Toyota',2011, 17000,'Sedan'),
('Vitz','Toyota',2014, 15000,'Hatchback'),
('Accord','Honda',2018, 28000,'Sedan'),
('7500','BMW',2015, 50000,'Sedan'),
('Parado','Toyota',2011, 25000,'SUV'),
('C200','Mercedez',2010, 26000,'Sedan'),
('Corrolla','Toyota',2014, 19000,'Sedan'),
('Civic','Honda',2015, 20000,'Sedan')

En el script anterior, creamos la base de datos Showroom con una tabla Car. La tabla Car tiene cinco atributos:CarId, Name, Make, Model, Price y Type.

A continuación, agregamos 12 registros ficticios en la tabla Car.

Ahora, verá cada una de las funciones de clasificación.

1. Función de rango

La función de rango en el servidor SQL asigna rango a cada registro ordenado por la cláusula ORDER BY. Por ejemplo, si desea ver el quinto auto más caro en la tabla de autos, puede usar la función de clasificación de la siguiente manera:

Use Showroom
SELECT Name,Make,Model, Price, Type,
RANK() OVER(ORDER BY Price DESC) as PriceRank
FROM Car

En la secuencia de comandos anterior, seleccione el nombre, la marca, el modelo, el precio, el tipo y el rango de cada automóvil ordenado por precio como la columna "PriceRank". La sintaxis de la función Rank es simple. Tienes que escribir la función RANK seguida del operador OVER. Dentro del operador OVER, debe pasar la cláusula ORDER BY que ordena los datos. El resultado del script anterior se ve así:

Puedes ver la clasificación de cada coche. Es importante mencionar que si hay un empate entre los rangos de dos registros, se salta la siguiente posición en el ranking. Por ejemplo, hay un empate entre el registro 5 y 6 en la salida. Tanto el Parado como el Civic tienen precios iguales y, por lo tanto, se han clasificado en el puesto 5. Sin embargo, el siguiente puesto, en particular, el puesto 6, se omite y los dos coches siguientes de la lista se han clasificado en el puesto 7, ya que también tienen el mismo precio. Después del rango 7, el rango 8 se salta nuevamente y el siguiente rango asignado es el 9.

Puede dividir los datos en particiones y luego aplicar la clasificación a particiones individuales. En el siguiente script, se encuentra la partición de los registros por tipo. Clasificamos los autos dentro de cada partición.

SELECT Name,Make,Model, Price, Type,
RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as PriceRank
FROM Car

El resultado del script anterior se ve así:

Es evidente a partir de la salida que los registros se han dividido según los tipos de automóviles y el rango se ha asignado localmente dentro de la partición. Por ejemplo, los primeros dos registros pertenecen a la partición "Hatchback" y se clasificaron en 1 y 2. Para la siguiente partición, es decir, "Sedán", la clasificación se restablece a 1.

2. Función Dense_Rank

La función dense_rank es similar a la función de rango. Sin embargo, en el caso de dense_rank, si hay un empate entre dos registros en términos de rango, no se salta el siguiente rango. A ver lo demostramos con el ejemplo. Ejecute el siguiente script:

Use Showroom
SELECT Name,Make,Model, Price, Type,
DENSE_RANK() OVER(ORDER BY Price DESC) as DensePriceRank
FROM Car

Una vez más, puede ver que los registros 5 y 6 tienen el mismo valor para Precio y a ambos se les ha asignado el rango 5. Sin embargo, a diferencia de la función de rango que omite el siguiente rango, la función dense_rank no omite el siguiente rango y el rango 6 ha sido asignado al siguiente registro.

Al igual que la función de clasificación, la función dense_rank también se puede aplicar a la cláusula de partición por. Mira el siguiente guión:

SELECT Name,Make,Model, Price, Type,
DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank
FROM Car

El resultado del script anterior se ve así:

3. Función número_fila

La función número_fila también clasifica los registros según las condiciones especificadas por la cláusula ORDER BY. Sin embargo, a diferencia de las funciones rank y dense_rank, la función row_number no asigna el mismo rango donde hay valores duplicados para la columna especificada por la cláusula ORDER BY. Mira el siguiente guión:

SELECT Name,Make,Model, Price, Type,
DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank
FROM Car

El resultado del script anterior se ve así:

En la secuencia de comandos anterior, puede ver que los registros 5 y 6 tienen el mismo valor para la columna Precio, pero el rango que se les asigna es diferente.

De manera similar, la función número_fila se puede aplicar a los datos particionados. Mire la siguiente secuencia de comandos, por ejemplo.

SELECT Name,Make,Model, Price, Type,
ROW_NUMBER() OVER(PARTITION BY Type ORDER BY Price DESC) AS PriceRankRow
FROM Car

El resultado del script anterior se ve así:

4. Función NTILE

La función NTILE agrupa el ranking. Suponga que tiene 12 registros en una tabla y desea clasificarlos en grupos de 4. Los primeros tres registros tendrán el rango 1, los siguientes tres registros tendrán el rango 2 y así sucesivamente.

Echemos un vistazo a un ejemplo de la función NTILE.

Use Showroom
SELECT Name,Make,Model, Price, Type,
NTILE(4) OVER(ORDER BY Price DESC) as NtilePrice
FROM Car

En el script anterior, pasamos 4 como parámetro a la función NTILE. Como tenemos 12 registros, verá un total de 4 rangos diferentes donde se asignará 1 rango a tres registros. La salida se ve así:

Puede ver que los tres primeros autos más caros se clasificaron en el puesto 1, los siguientes tres se clasificaron en el puesto 2 y así sucesivamente.

La función NTILE también se puede aplicar a los datos particionados. Mira el siguiente guión:

SELECT Name,Make,Model, Price, Type,
NTILE(4) OVER(PARTITION BY Type ORDER BY Price DESC) as NtilePrice
FROM Car

Conclusión

Las funciones de clasificación en SQL Server se utilizan para clasificar los datos de diferentes maneras. En esta lectura, presentamos diferentes tipos de funciones de clasificación con los ejemplos. Las funciones rank y dense_rank otorgan el mismo rango a los datos con los mismos valores en la cláusula ORDER BY, mientras que la función row_number clasifica el registro de forma incremental incluso si hay un empate.
En caso de que no haya registros duplicados en la columna especificada por la cláusula ORDER BY, las funciones rank, dense_rank y row_number se comportan de manera similar.