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

Calculer le centile à partir de la récence dans MySQL

Parfois, vous voudrez peut-être calculer le centile à partir de la récence dans MySQL en fonction de. Par exemple, pour classer les clients en fonction de la récence des achats ou des commandes au lieu du total des ventes. Cela permet de créer des offres spéciales pour les personnes qui ont récemment acheté quelque chose sur votre site Web. Il n'y a pas encore de fonctions pour cela. 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 souhaitez calculer le centile à partir de la récence des commandes.

order
+-----------+------------+------------------+
|  user_id  |   product  |   purchase_date  |
+-----------+------------+------------------+
|     1     |     Soap   |     2013-11-20   |
|     4     |   Perfume  |     2013-07-02   |
|     1     |   Noodles  |     2013-10-20   |
|     4     |     Soap   |     2013-11-11   |
|     1     |    Glue    |     2013-09-12   |
|     3     |     Deo    |     2013-10-20   |
+-----------+------------+------------------+
percentiles
+-----------+----------------+---------+---------------+
|  user_id  |   latest       |  rank   |   percentile  |
+-----------+----------------+---------+---------------+
|     1     |  2013-11-20    |    1    |      100      |
|     4     |  2013-11-11    |    2    |     66.67     |
|     3     |  2013-10-20    |    3    |     33.33     |
+-----------+----------------+---------+---------------+

Voici une requête que vous pouvez utiliser pour calculer le centile à partir de la récence dans MySQL. Remplacez simplement les colonnes - user_id, purchase_date et table - order. Il obtient la dernière date d'achat de chaque utilisateur. Ensuite, il les classe au plus tard sur la date d'achat. Enfin, il calcule le centile à l'aide du rang.

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

Si vous avez déjà la dernière date d'achat pour chaque utilisateur dans le tableau et que vous souhaitez utiliser directement le tableau pour calculer le centile à partir de la récence de l'achat, voici une requête

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

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

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  |   purchase_date|  rank   |   percentile  |
+-----------+----------------+---------+---------------+
|     1     |  2013-11-20    |    1    |     66.67     |
|     4     |  2013-11-11    |    2    |     33.33     |
|     3     |  2013-10-20    |    3    |       0       |
+-----------+----------------+---------+---------------+

SQL pour créer l'exemple d'ordre de table :