【问题标题】:Create column for the quantile number of a value in BigQuery为 BigQuery 中值的分位数创建列
【发布时间】:2019-02-05 19:19:04
【问题描述】:

我有一个包含两列的表:idscore。我想创建第三列,它等于个人score 所在的分位数。我想在 BigQuery 的标准 SQL 中执行此操作。

这里是my_table

+----+--------+
| id | score  |
+----+--------+
|  1 |      2 |
|  2 |     13 |
|  3 |     -2 |
|  4 |      7 |
+----+--------+

然后我想要下表(以四分位数显示的示例,但我对四分位数/五分位数/十分位数感兴趣)

+----+--------+----------+
| id | score  | quaRtile |
+----+--------+----------+
|  1 |      2 |        2 |
|  2 |     13 |        4 |
|  3 |     -2 |        1 |
|  4 |      7 |        3 |
+----+--------+----------+

如果这适用于 1 亿行,那就太好了。我环顾四周,看到一些似乎使用legacy sql 的解决方案,而solutions using RANK() 函数似乎不适用于非常大的数据集。谢谢!

【问题讨论】:

  • 你如何定义“分位数”?
  • 感谢您的评论@GordonLinoff。这个玩具示例使用四分位数,但我对五分位数或十分位数的兴趣与四分位数一样多。我添加了一些语言来解释。
  • 您想要添加列并更新它的解决方案吗?

标签: sql google-bigquery bigquery-standard-sql


【解决方案1】:

如果我理解正确,您可以使用ntile()。例如,如果你想要一个 1-4 的值,你可以这样做:

select t.*, ntile(4) over (order by score) as tile
from t;

如果要枚举值,请使用rank()dense_rank()

select t.*, rank() over (order by score) as tile
from t;

我明白了,您的问题是让代码正常工作,因为如果没有 partition by,BigQuery 往往会耗尽资源。一种方法是将分数分成不同的组。我认为这个逻辑可以满足您的需求:

select *, 
       ( (count(*) over (partition by cast(score / 1000 as int64) order by cast(score / 1000 as int64)) -
          count(*) over (partition by cast(score / 1000 as int64))
         ) +
         rank() over (partition by cast(score / 1000 as int64) order by regi_id)
      ) as therank,
      -- rank() over (order by score) as therank
from t;

这会将分数分成 1000 组(对于整数来说可能太多了)。然后重构排名。

如果您的分数具有相对较低的基数,则 join 聚合有效:

select t.*, (running_cnt - cnt + 1) as therank
from t join
     (select score, count(*) as cnt, sum(count(*)) over (order by score) as running_cnt
      from t
      group by score
     ) s
     on t.score = s.score;

一旦有了rank()(或row_number()),您就可以自己轻松地计算图块(提示:除法)。

【讨论】:

    【解决方案2】:

    输出建议我rank()

    SELECT *, RANK() OVER (ORDER BY score) as quantile 
    FROM table t
    ORDER BY id;
    

    【讨论】:

      猜你喜欢
      • 2021-10-05
      • 2018-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多