【问题标题】:Create the width_bucket function from Oracle SQL in BigQuery在 BigQuery 中从 Oracle SQL 创建 width_bucket 函数
【发布时间】:2020-07-23 00:44:43
【问题描述】:

我希望通过 BigQuery 中的新函数复制 Oracle 中可用的 width_bucket 函数。该函数根据您在最小值和最大值之间指定的数字创建等宽桶。例如,width_bucket(user_count, 0, 35, 10) 将创建 10 个相等的桶,例如 0 - 3.5、3.5 - 7 等,并告诉您 user_count 属于哪个桶。任何帮助将不胜感激!

Oracle 文档 - https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions214.htm

这是我所拥有的,我相信这是可行的,但我想得到它,所以如果可能的话,我不必引用表格来生成行号。

CREATE OR REPLACE FUNCTION functions.widthBucket(
  value NUMERIC,
  minValue NUMERIC,
  maxValue NUMERIC,
  buckets INT64)
AS ((
  SELECT resultBucket 
  FROM (
      SELECT CASE 
               WHEN value >= (minValue * bucketNumber) + ((maxValue/buckets) * (bucketNumber - 1))
                AND value < (maxValue/buckets) * bucketNumber 
               THEN bucketNumber
               WHEN value = maxValue and bucketNumber = buckets 
               THEN bucketNumber
             ELSE -1 
             END as resultBucket
      FROM (
            SELECT ROW_NUMBER() OVER (PARTITION BY '') as bucketNumber
            FROM project.dateTable
           ) x
      WHERE bucketNumber <= buckets) x
  WHERE resultBucket != -1
  ));

【问题讨论】:

  • 您能否提供您计划如何使用此类 UDF 的示例 - 带有一些用于测试的虚拟数据 :o) 询问,因为我似乎不明白该表在函数内部做什么

标签: google-bigquery


【解决方案1】:

以下是 BigQuery 标准 SQL

试试下面 - 我认为它完全符合您的要求

CREATE TEMP FUNCTION widthBucket(
  value NUMERIC, 
  minValue NUMERIC, 
  maxValue NUMERIC, 
  buckets NUMERIC
) AS (
  RANGE_BUCKET(value, GENERATE_ARRAY(minValue, maxValue, (maxValue - minValue)/buckets))
);

使用就像你的问题一样简单 例如widthBucket(user_count, 0, 35, 10)

当值等于 maxValue 时解决边缘情况 - 使用上面的以下变化

CREATE TEMP FUNCTION widthBucket(
  value NUMERIC, 
  minValue NUMERIC, 
  maxValue NUMERIC, 
  buckets NUMERIC
) AS ((
  SELECT IF(bucket > buckets, buckets, bucket)
  FROM (
    SELECT RANGE_BUCKET(value, GENERATE_ARRAY(minValue, maxValue, (maxValue - minValue)/buckets)) bucket
  )
));

【讨论】:

  • 啊,是的,它工作得很好,而且更干净。但是有一个问题,如果将值设置为等于 maxValue,则结果是 buckets + 1。有想法吗?
  • 当然。这种行为是有道理的,因为它是 RANGE_BUCKET 的工作方式。因此,请参阅答案中的更新以处理这种情况
猜你喜欢
  • 2021-02-03
  • 2012-01-20
  • 1970-01-01
  • 2013-08-08
  • 1970-01-01
  • 2017-11-10
  • 2016-08-09
  • 2014-12-02
  • 1970-01-01
相关资源
最近更新 更多