Mysql
 sql >> Database >  >> RDS >> Mysql

Calcola percentile in MySQL in base ai totali

Può essere difficile calcolare il percentile in MySQL. Non ci sono ancora funzioni per questo. I percentili sono utili per classificare e raggruppare utenti o clienti.

Puoi identificare i tuoi utenti o clienti più preziosi e creare offerte speciali per loro. Ecco una query pronta per farlo.

Ad esempio, hai una tabella ordini che contiene tutti gli ordini di prodotti per ciascun utente. Vuoi calcolare il percentile.

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

Ecco una query che puoi utilizzare per calcolare il percentile in MySQL in base ai totali. Basta sostituire le colonne – user_id, sales e table – order. Aggrega le vendite totali per ciascun utente. Quindi li classifica sulle vendite totali. Infine, calcola il percentile usando il 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

Se hai già vendite totali per ogni utente nella tabella e desideri utilizzare direttamente la tabella per calcolare il percentile, ecco una query

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

Come puoi vedere l'ultimo utente classificato non ha un percentile zero. Questa è la natura del calcolo percentile. O la prima persona può avere il 100 percentile o l'ultima classificata può avere zero. Entrambi non possono accadere contemporaneamente. Se vuoi forzare l'ultima persona classificata ad avere un percentile zero, puoi utilizzare le seguenti query. Non sto aggiungendo 1 al rango durante il calcolo del percentile.

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 hai già vendite totali per ogni utente nella tabella e desideri utilizzare direttamente la tabella per calcolare il percentile, ecco una query

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 per creare l'ordine della tabella di esempio: