32

令人惊讶的是,我找不到 postgresql 的第 n 个百分位函数。

我通过 mondrian olap 工具使用它,所以我只需要一个返回 95% 的聚合函数。

我确实找到了这个链接:

http://www.postgresql.org/message-id/162867790907102334r71db0227jfa0e4bd96f48b8e4@mail.gmail.com

但由于某种原因,该百分位函数中的代码在某些情况下会返回空值,并进行某些查询。我检查了数据,数据中似乎没有什么奇怪的原因!

4

2 回答 2

44

在 PostgreSQL 9.4 中,现在有对百分位数的原生支持,在Ordered-Set Aggregate Functions中实现:

percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression) 

连续百分位数:返回与排序中指定分数相对应的值,如果需要,在相邻输入项之间进行插值

percentile_cont(fractions) WITHIN GROUP (ORDER BY sort_expression)

多个连续百分位数:返回与分数参数的形状匹配的结果数组,每个非空元素替换为对应于该百分位数的值

有关更多详细信息,请参阅文档:http ://www.postgresql.org/docs/current/static/functions-aggregate.html

并在这里查看一些示例:https ://github.com/michaelpq/michaelpq.github.io/blob/master/_posts/2014-02-27-postgres-9-4-feature-highlight-within-group.markdown

CREATE TABLE aa AS SELECT generate_series(1,20) AS a;
--SELECT 20

WITH subset AS (
    SELECT a AS val,
        ntile(4) OVER (ORDER BY a) AS tile
    FROM aa
)
SELECT tile, max(val)
FROM subset GROUP BY tile ORDER BY tile;

 tile | max
------+-----
    1 |   5
    2 |  10
    3 |  15
    4 |  20
(4 rows)
于 2015-01-05T17:04:20.577 回答
22

ntile功能在这里非常有用。我有一张桌子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)按分数对列进行排序,将其分成四个偶数组(如果数字均分)并根据顺序分配组号。

因为我在这里有 8 个数字,它们代表第 0、第 12.5、第 25、第 37.5、第 50、第 62.5、第 75 和第 87.5 个百分位数。因此,如果我只取quartile2 的结果,我将得到第 25 和第 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;

返回4, 8 列表中第三高的数字。

如果您有一个更大的表并使用ntile(100)您过滤的列将是百分位数,您可以使用与上面相同的查询。

于 2014-10-07T17:09:59.453 回答