Mysql
 sql >> Base de données >  >> RDS >> Mysql

Calculer le centile dans MySQL en fonction des totaux

Il peut être pénible de calculer le centile dans MySQL. Il n'y a pas encore de fonctions pour cela. Les centiles sont utiles pour classer et regrouper les utilisateurs ou les clients.

Vous pouvez identifier vos utilisateurs ou clients les plus précieux et créer des offres spéciales pour eux. Voici une requête toute faite pour le faire.

Par exemple, vous avez une table commandes qui contient toutes les commandes de produits pour chaque utilisateur. Vous voulez calculer le centile.

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       |
+-----------+----------+---------+---------------+

Voici une requête que vous pouvez utiliser pour calculer le centile dans MySQL en fonction des totaux. Remplacez simplement les colonnes - user_id, sales et table - order. Il agrège les ventes totales pour chaque utilisateur. Ensuite, il les classe sur les ventes totales. Enfin, il calcule le centile à l'aide du rang.

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 vous avez déjà le total des ventes pour chaque utilisateur dans le tableau et que vous souhaitez utiliser directement le tableau pour calculer le centile, voici une requête

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       |
+-----------+----------+---------+---------------+

Comme vous pouvez le voir, le dernier utilisateur classé n'a pas de centile zéro. C'est la nature du calcul du centile. Soit la première personne peut avoir 100 centiles, soit la dernière classée peut avoir zéro. Les deux ne peuvent pas arriver en même temps. Si vous souhaitez forcer la dernière personne classée à avoir un centile zéro, vous pouvez utiliser les requêtes suivantes. Je n'ajoute pas 1 au rang lors du calcul du centile.

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 vous avez déjà le total des ventes pour chaque utilisateur dans le tableau et que vous souhaitez utiliser directement le tableau pour calculer le centile, voici une requête

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 pour créer l'exemple d'ordre de table :