在aws athena中计算百分位数

calculating percentiles in aws athena

aws quicksight 正在使用我的查询结果。尽管 quicksight 提供了 percentileCont() 来为我们完成这项工作,但我想在查询中使用它而不是使用计算字段。

最终我想做的是创建一个点列,其中

under 25percentile -> 0
under 50 percentile -> 1 
under 75 percentile -> 2
rest -> 3

取决于范围从 [a, b] 的列。

现在我找出每个百分位数的值并手动创建一个范围

With table as (
    SELECT *
         , cast(date_diff('day', last_transaction, current_date) as double) as col
)
SELECT *
     , case 
         when col between 0 and 25 then 0
         when col between 26 and 66 then 1
         when col between 67 and 193 then 2
         when col >= 194 then 3
       end as point
  FROM table;

但是我想让它动态化,所以 [0,25] 应该是 [min(col), 25percentile(col)].

以上查询输出

col   point
333     3
166     2
 96     1
 .

添加了 NTILE() 感谢@Gordon Linoff

With table as (
    SELECT *
         , cast(date_diff('day', last_transaction, current_date) as double) as col
)
SELECT *
     , case 
         when col between 0 and 25 then 0
         when col between 26 and 66 then 1
         when col between 67 and 193 then 2
         when col >= 194 then 3
       end as point
      , NTILE(4) over(order by col) as pt
  FROM table;

产出

col   point
0     1
0     1
0     1
 .

似乎搞乱了 col 计算

在 Presto 中,我认为 approx_percentile() 和一个 case 表达式可以做你想做的事:

select t.*, 
    case
        when col <= approx_percentile(col, 0.25) over() then 0
        when col <= approx_percentile(col, 0.50) over() then 1
        when col <= approx_percentile(col, 0.75) over() then 2
        else 3
    end as point
from mytable t

您几乎描述了 ntile() 函数:

SELECT t.*,,
       NTILE(4) OVER (ORDER BY col) - 1 as point
FROM table;

两个警告:

  • NTILE(<n>) returns 值介于 1 和 n
  • 之间
  • NTILE() 确保生成的图块相等。这意味着边界上的值最终可能会出现在不同的容器中。

另一种将值放在单独的容器中(但容器可能具有不同大小)的替代方法是 percent_rank()。在你的情况下:

SELECT t.*,,
       CEILING(PRECENT_RANK() OVER (ORDER BY col) * 4) - 1 as point
FROM table;