web-dev-qa-db-fra.com

calculs du nième percentile dans postgresql

J'ai été étonnamment incapable de trouver une fonction du nième centile pour postgresql.

J'utilise cet outil via mondrian olap donc j'ai juste besoin d'une fonction d'agrégation qui renvoie un 95e centile.

J'ai trouvé ce lien:

http://www.postgresql.org/message-id/[email protected]

Mais pour une raison quelconque, le code de cette fonction centile renvoie des valeurs nulles dans certains cas avec certaines requêtes. J'ai vérifié les données et il n'y a rien d'étrange dans les données qui semblent causer cela!

21
Codek

Avec PostgreSQL 9.4, il existe désormais une prise en charge native des centiles, implémentée dans Fonctions d'agrégation d'ensemble ordonné :

percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression) 

percentile continu: renvoie une valeur correspondant à la fraction spécifiée dans l'ordre, interpolant entre les éléments d'entrée adjacents si nécessaire

percentile_cont(fractions) WITHIN GROUP (ORDER BY sort_expression)

multiple centile continu: renvoie un tableau de résultats correspondant à la forme du paramètre fractions, chaque élément non nul étant remplacé par la valeur correspondant à ce centile

Voir la documentation pour plus de détails: http://www.postgresql.org/docs/current/static/functions-aggregate.html

et voir ici pour quelques exemples: https://github.com/michaelpq/michaelpq.github.io/blob/master/_posts/2014-02-27-postgres-9-4-feature-highlight-within -group.markdown

32
alfonx

La fonction ntile est très utile ici. J'ai une table test_temp:

select * from test_temp

score
integer
3
5
2
10
4
8
7
12

select score, ntile(4) over (order by score) as quartile from test_temp;

score    quartile
integer  integer
2        1
3        1
4        2
5        2
7        3
8        3
10       4
12       4

ntile(4) over (order by score) trie les colonnes par score, les divise en quatre groupes pairs (si le nombre se divise également) et attribue le numéro de groupe en fonction de l'ordre.

Puisque j'ai 8 chiffres ici, ils représentent les 0e, 12,5e, 25e, 37,5e, 50e, 62,5e, 75e et 87,5e centiles. Donc, si je ne prends que les résultats où quartile est 2, j'aurai les 25e et 37,5e centiles.

with ranked_test as (
    select score, ntile(4) over (order by score) as quartile from temp_test
)
select min(score) from ranked_test
where quartile = 2
group by quartile;

renvoie 4, le troisième chiffre le plus élevé de la liste des 8.

Si vous aviez une table plus grande et utilisiez ntile(100) la colonne sur laquelle vous filtrer serait le centile, et vous pourriez utiliser la même requête que ci-dessus.

18
Mike

Comme dans les commentaires ci-dessus, la solution est là, assurez-vous simplement d'ajouter à la fois les fonctions de tri de tableau et de percentile_cont!

https://stackoverflow.com/a/14309370/330315

1
Codek