我有一个名为“计时”的表,其中存储了 100 万个用于负载测试的响应计时,现在我们需要将此数据分为 100 组,即前 500 条记录作为一组,依此类推,并计算每组的百分位数,而不是平均值.
到目前为止我尝试过这个查询
Select quartile
, avg(data)
, max(data)
FROM (
SELECT data
, ntile(500) over (order by data) as quartile
FROM data
) x
GROUP BY quartile
ORDER BY quartile
但是我如何找到百分位数
通常,如果您想知道百分位数,使用
cume_dist
比使用 ntile
更安全。这是因为当输入很少时,ntile
的行为会很奇怪。考虑:
=# select v,
ntile(100) OVER (ORDER BY v),
cume_dist() OVER (ORDER BY v)
FROM (VALUES (1), (2), (4), (4)) x(v);
v | ntile | cume_dist
---+-------+-----------
1 | 1 | 0.25
2 | 2 | 0.5
4 | 3 | 1
4 | 4 | 1
您可以看到
ntile
仅使用 100 个桶中的前 4 个,其中 cume_dist
始终为您提供从 0 到 1 的数字。因此,如果您想找出第 99 个百分位数,您可以将所有内容都扔掉a cume_dist
低于 0.99,并从剩下的内容中取最小的 v
。
percentile_cont
和 percentile_disc
会让事情变得更加容易,因为您不必自己构建存储桶。前者甚至可以在值之间进行插值,如果您的数据集较小,这可能会很有用。
编辑:
请注意,自从我最初回答这个问题以来,Postgres 已经获得了额外的聚合函数来帮助解决这个问题。请参阅
percentile_disc
和 percentile_cont
此处。这些是在 9.4 中引入的。
原答案:
ntile
是计算百分位数的方式(以及其他 n 分位数,例如四分位数、十分位数等)。
ntile
将表尽可能均等地分组到指定数量的桶中。如果您指定 4 个存储桶,则这将是一个四分位数。 10 就是十分之一。
对于 percentile,您可以将存储桶数量设置为 100。
我不确定 500 是从哪里来的...如果您想确定您的数据位于哪个百分位数(即,将百万个计时尽可能平均地划分为 100 个桶),您可以使用
ntile
与参数为 100,组将有超过 500 个条目。
如果您不关心
avg
也不关心 max
,您可以从查询中删除一堆内容。所以它看起来像这样:
SELECT data, ntile(100) over (order by data) AS percentile
FROM data
ORDER BY data