Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Calcular percentil no MySQL com base nos totais


Pode ser difícil calcular o percentil no MySQL. Ainda não há funções para isso. Os percentis são úteis para classificar e agrupar usuários ou clientes.

Você pode identificar seus usuários ou clientes mais valiosos e criar ofertas especiais para eles. Aqui está uma consulta pronta para fazer isso.

Por exemplo, você tem uma tabela pedidos que contém todos os pedidos de produtos para cada usuário. Você deseja calcular o 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       |
+-----------+----------+---------+---------------+

Aqui está uma consulta que você pode usar para calcular o percentil no MySQL com base nos totais. Basta substituir as colunas – user_id, vendas e tabela – ordem. Ele agrega as vendas totais de cada usuário. Em seguida, ele os classifica nas vendas totais. Por fim, calcula o percentil usando a classificação.
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

Se você já tem vendas totais para cada usuário na tabela e deseja usar diretamente a tabela para calcular o percentil, aqui está uma 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 você pode ver, o último usuário classificado não tem um percentil zero. Esta é a natureza do cálculo do percentil. Ou a primeira pessoa pode ter 100 percentil ou a última classificada pode ter zero. Ambos não podem acontecer ao mesmo tempo. Se você quiser forçar a última pessoa classificada a ter um percentil zero, você pode usar as seguintes consultas. Não estou adicionando 1 à classificação ao calcular o 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

Se você já tem vendas totais para cada usuário na tabela e deseja usar diretamente a tabela para calcular o percentil, aqui está uma 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 criar a ordem da tabela de amostra: