使用 SQL 的百分位数

Posted

技术标签:

【中文标题】使用 SQL 的百分位数【英文标题】:Percentile using SQL 【发布时间】:2017-03-05 11:30:04 【问题描述】:

我的数据集中有 3 列:

    货币 新近度 频率

我想使用 SQL 创建另外 3 个列,例如 M_P、R_Q、F_Q,其中包含货币、新近度和频率值中每个值的百分位值。

提前谢谢你。

Customer_ID    Frequency Recency    Monetary    R_Q     F_Q        M_Q
112                 1      39          7.05      0.398   0.789    0.85873
143                 1      23          0.1833    0.232  0.7895   0.1501
164                 1      52          0.416      0.508   0.789  0.295
123                 1      118          1.1        0.98   0.789  0.52

【问题讨论】:

你应该用你正在使用的数据库标记你的问题。 您是否只想将列除以 100?给出一些样本数据和预期的输出。还要提到数据库版本 我想要每个值的百分位数。 我正在使用 Spark SQL 编辑器。 这个“百分等级”是如何计算的?为什么0.789Frequency 1 【参考方案1】:

你要找的函数是ANSI标准函数ntile()

select t.*,
       ntile(100) over (order by monetary) as percentile_monetary,
       ntile(100) over (order by recency) as percentile_recency,
       ntile(100) over (order by frequency) as percentile_frequency
from t;

这在大多数数据库中都可用。

您可以使用rank()count() 计算百分位数。根据您想要处理平局的方式以及您想要 1-100 还是 0-100 的值,以下应该是一个很好的起点:

select t.*,
       (1 + rank_monetary * 100.0 / cnt) as percentile_monetary,
       (1 + rank_recency * 100.0 / cnt) as percentile_recency,
       (1 + rank_frequency * 100.0 / cnt) as percentile_frequency
from (select t.*,
             count(*) over () as cnt,
             rank() over (order by monetary) - 1 as rank_monetary,
             rank() over (order by recency) - 1 as rank_recency,
             rank() over (order by frequency) - 1 as rank_frequency
      from t
     ) t;

【讨论】:

@玉兰油。 . . Spark 支持窗口函数和 ntile() 有一段时间了 (spark.apache.org/docs/2.1.0/api/java/org/apache/spark/sql/…)。 ntile() 将整数值设为 1、2.... 等等。我想要的是上面提到的排名百分位数。 嗨,你能解释一下 (1 + rank_monetary * 100.0 / cnt) 在做什么吗? 它将排名转换为 1 到 100 之间的值。

以上是关于使用 SQL 的百分位数的主要内容,如果未能解决你的问题,请参考以下文章

如何计算基于组的分位数?

如何计算列的每个值所在的百分位数? (Spark SQL)[重复]

Pandas .. 分位数函数是不是需要排序数据来计算百分位数?

JavaScript中的分位数/百分点/百分位数/逆累积分布函数

如何在 JavaScript(或 PHP)中获取数组的中位数和四分位数/百分位数?

使用 SQL 的百分位数