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

Calcular percentil da frequência no MySQL


Às vezes você pode querer calcular percentil de frequência ou contagens no MySQL com base em. Por exemplo, para classificar os clientes com base no número de compras ou pedidos em vez do total de vendas. Ainda não há funções para isso. 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 da frequência dos pedidos.
order
+------+--------------+-------------+
|  user_id  |   product  |   sales  |
+-----------+------------+----------+
|     1     |     Soap   |    10    |
|     4     |   Perfume  |   100    |
|     1     |   Noodles  |   20     |
|     4     |     Soap   |   10     |
|     1     |    Glue    |   20     |
|     3     |     Deo    |   200    |
+-----------+------------+----------+
percentiles
+-----------+----------+---------+---------------+
|  user_id  |   total  |  rank   |   percentile  |
+-----------+----------+---------+---------------+
|     1     |     3    |    1    |      100      |
|     4     |     2    |    2    |     66.67     |
|     3     |     1    |    3    |     33.33     |
+-----------+----------+---------+---------------+

Aqui está uma consulta que você pode usar para calcular o percentil da frequência ou contagem no MySQL. Basta substituir as colunas – user_id, vendas e tabela – ordem. Ele conta o número de pedidos para cada usuário. Em seguida, ele os classifica em número de pedidos. 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,count(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 o número de pedidos para cada usuário na tabela e deseja usar diretamente a tabela para calcular o percentil de frequência ou contagem, 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     |    3     |
|     4     |    2     |
|     3     |    1     |
+-----------+----------+
percentiles
+-----------+----------+---------+---------------+
|  user_id  |   total  |  rank   |   percentile  |
+-----------+----------+---------+---------------+
|     1     |     3    |    1    |      100      |
|     4     |     2    |    2    |     66.67     |
|     3     |     1    |    3    |     33.33     |
+-----------+----------+---------+---------------+

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,count(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     |    3     |    1    |     66.67     |
|     4     |    2     |    2    |     33.33     |
|     3     |    1     |    3    |       0       |
+-----------+----------+---------+---------------+

SQL para criar a ordem da tabela de amostra: