sql >> Base de Datos >  >> RDS >> Mysql

Calcular percentil en MySQL basado en totales

Puede ser una molestia calcular el percentil en MySQL. Todavía no hay funciones para él. Los percentiles son útiles para clasificar y agrupar usuarios o clientes.

Puede identificar a sus usuarios o clientes más valiosos y crear ofertas especiales para ellos. Aquí hay una consulta preparada para hacerlo.

Por ejemplo, tiene una tabla pedidos que contiene todos los pedidos de productos para cada usuario. Quiere calcular el percentil.

order
+-----------+------------+----------+
|  user_id  |   product  |   sales  |
+-----------+------------+----------+
|     1     |     Soap   |    10    |
|     4     |   Perfume  |   100    |
|     1     |   Noodles  |   20     |
|     3     |     Deo    |   200    |
+-----------+------------+----------+
percentiles
+-----------+----------+---------+---------------+
|  user_id  |   total  |  rank   |   percentile  |
+-----------+----------+---------+---------------+
|     1     |    30    |    3    |     33.33     |
|     4     |   100    |    2    |     66.67     |
|     3     |   200    |    1    |     100       |
+-----------+----------+---------+---------------+

Aquí hay una consulta que puede usar para calcular el percentil en MySQL en función de los totales. Simplemente reemplace las columnas:ID de usuario, ventas y tabla:orden. Agrega las ventas totales de cada usuario. Luego los clasifica en ventas totales. Finalmente, calcula el percentil usando el rango.

select user_id,total,rank,round(100*(cnt-rank+1)/cnt,0) as percentile from   
(SELECT  user_id,total,@curRank := @curRank + 1 AS rank
FROM      (select user_id,sum(sales) as total from `order` group by user_id)
p, (SELECT @curRank := 0) r
ORDER BY  total desc ) as dt,(select count(distinct user_id) as cnt from
`order`) as ct

Si ya tiene las ventas totales de cada usuario en la tabla y quiere usar directamente la tabla para calcular el percentil, aquí tiene una consulta

select user_id,total,rank,round(100*(cnt-rank+1)/cnt,0) as percentile from   
(SELECT  user_id,total,@curRank := @curRank + 1 AS rank
FROM   `order`
p, (SELECT @curRank := 0) r
ORDER BY  total desc ) as dt,(select count(distinct user_id) as cnt from
`order`) as ct
order
+-----------+----------+
|  user_id  |   total  |
+-----------+----------+
|     1     |    30    |
|     4     |   100    |
|     3     |   200    |
+-----------+----------+
percentiles
+-----------+----------+---------+---------------+
|  user_id  |   total  |  rank   |   percentile  |
+-----------+----------+---------+---------------+
|     1     |    30    |    3    |     33.33     |
|     4     |   100    |    2    |     66.67     |
|     3     |   200    |    1    |     100       |
+-----------+----------+---------+---------------+

Como puede ver, el último usuario clasificado no tiene un percentil cero. Esta es la naturaleza del cálculo de percentiles. La primera persona puede tener un percentil 100 o la última clasificada puede tener cero. Ambos no pueden ocurrir al mismo tiempo. Si desea forzar a la última persona clasificada a tener un percentil cero, puede usar las siguientes consultas. No estoy agregando 1 al rango al calcular el percentil.

select user_id,total,rank,round(100*(cnt-rank)/cnt,0) as percentile from   
(SELECT  user_id,total,@curRank := @curRank + 1 AS rank
FROM      (select user_id,sum(sales) as total from `order` group by user_id)
p, (SELECT @curRank := 0) r
ORDER BY  total desc ) as dt,(select count(distinct user_id) as cnt from
`order`) as ct

Si ya tiene las ventas totales de cada usuario en la tabla y desea usar directamente la tabla para calcular el percentil, aquí tiene una consulta

select user_id,total,rank,round(100*(cnt-rank)/cnt,0) as percentile from   
(SELECT  user_id,total,@curRank := @curRank + 1 AS rank
FROM   `order`
p, (SELECT @curRank := 0) r
ORDER BY  total desc ) as dt,(select count(distinct user_id) as cnt from
`order`) as ct
percentiles
+-----------+----------+---------+---------------+
|  user_id  |   total  |  rank   |   percentile  |
+-----------+----------+---------+---------------+
|     1     |    30    |    3    |        0      |
|     4     |   100    |    2    |     33.33     |
|     3     |   200    |    1    |     66.67     |
+-----------+----------+---------+---------------+

SQL para crear el orden de la tabla de muestra: