Blog de Gonzalo

FUNCIÓN RANK DE MYSQL

Hoy he descubierto la función rank de mysql. La función RANK asigna un rango a cada fila dentro de la partición de un conjunto de resultados. El rango de una fila se especifica en uno más el número de rangos que le preceden.
La sintaxis de RANK es:

RANK() OVER (
    PARTITION BY [{,...}]
    ORDER BY  [ASC|DESC], [{,...}]
)

Vamos a verlo con un ejemplo. Primero cargamos una tabla en nuestra base de datos
CREATE TABLE IF NOT EXISTS sales(
    sales_employee VARCHAR(50) NOT NULL,
    fiscal_year INT NOT NULL,
    sale DECIMAL(14,2) NOT NULL,
    PRIMARY KEY(sales_employee,fiscal_year)
);
 
INSERT INTO sales(sales_employee,fiscal_year,sale)
VALUES('Bob',2016,100),
      ('Bob',2017,150),
      ('Bob',2018,200),
      ('Alice',2016,150),
      ('Alice',2017,100),
      ('Alice',2018,200),
       ('John',2016,200),
      ('John',2017,150),
      ('John',2018,250);

Después de cargar la tabla se lanza la siguiente query:
SELECT
    sales_employee,
    fiscal_year,
    sale,
    RANK() OVER (PARTITION BY
                     fiscal_year
                 ORDER BY
                     sale DESC
                ) sales_rank
FROM
    sales;

Donde vemos que se usa la función rank y el resultado es:
sales_employee	fiscal_year	sale	sales_rank 	
    John 	   2016	        200.00      1  
    Alice 	   2016 	150.00 	    2
    Bob 	   2016 	100.00 	    3
    Bob 	   2017 	150.00 	    1
    John 	   2017 	150.00 	    1
    Alice 	   2017 	100.00 	    3
    John 	   2018 	250.00 	    1
    Bob 	   2018 	200.00 	    2
  Alice 	   2018 	200.00 	    2

¿Que significa el resultado?
  • Año 2016: John es el número 1 porque vendió 200 luego viene Alice que vendió 150 y luego Bob que vendió 100.
  • Año 2017: Bob y John están en el número 1 porque vendieron 150 y Alice que vendió 100 está la 3.
  • Año 2018: John está en el número 1 porque vendió 250 y Bob y Alice que vendieron 200 están la 2.

Si vais cambiando los valores entendereis mejor el funcionamiento de la función. Sobre todo por el año 2017.