function - cálculos del percentil n en postgresql
percentile (3)
Sorprendentemente, no he podido encontrar una función de percentil n para postgresql.
Estoy usando esto a través de la herramienta mondrian olap, así que solo necesito una función agregada que devuelva un percentil 95.
Encontré este enlace:
http://www.postgresql.org/message-id/[email protected]
Pero por alguna razón, el código en esa función de percentil está devolviendo nulos en algunos casos con ciertas consultas. ¡He comprobado los datos y no hay nada extraño en los datos que parezca causar eso!
Como en los comentarios anteriores, la solución está aquí, ¡solo asegúrate de agregar las funciones array y percentile_cont!
https://.com/a/14309370/330315
Con PostgreSQL 9.4 ahora hay soporte nativo para los percentiles, implementado en las funciones de agregados ordenados :
percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression)
percentil continuo: devuelve un valor correspondiente a la fracción especificada en el orden, interpolando entre elementos de entrada adyacentes si es necesario
percentile_cont(fractions) WITHIN GROUP (ORDER BY sort_expression)
percentil continuo múltiple: devuelve una serie de resultados que coinciden con la forma del parámetro fracciones, con cada elemento no nulo reemplazado por el valor correspondiente a ese percentil
Consulte la documentación para obtener más detalles: http://www.postgresql.org/docs/current/static/functions-aggregate.html
y vea aquí algunos ejemplos: https://github.com/michaelpq/michaelpq.github.io/blob/master/_posts/2014-02-27-postgres-9-4-feature-highlight-within-group.markdown
La función ntile
es muy útil aquí. Tengo una tabla 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)
ordena las columnas por puntaje, las divide en cuatro grupos pares (si el número se divide en partes iguales) y asigna el número de grupo según el orden.
Como tengo 8 números aquí, representan los percentiles 0, 12.5, 25, 37.5, 50, 62.5, 75 y 87.5. Entonces, si solo tomo los resultados donde el quartile
es 2, tendré los percentiles 25 y 37.5.
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;
devuelve 4
, el tercer número más alto en la lista de 8.
Si tuviera una tabla más grande y usara ntile(100)
la columna que filtre sería el percentil, y podría usar la misma consulta que la anterior.