在BigQuery中封装复杂代码

时间:2018-03-05 21:01:20

标签: google-bigquery user-defined-functions

我最近不得不从其他BQ表中生成BQ表。逻辑相当复杂,我最终编写了一个复杂的SQL语句。

在Oracle SQL中,我会编写一个PL / SQL过程,其逻辑分解为单独的部分(通常是合并语句)。在某些情况下,我会将一些代码封装到函数中。生成的过程将是一系列DML语句,易于阅读和维护。

然而,BQ没有类似的东西。 UDF只是临时的,不能存储在-say-视图中。

问题:我正在寻找使我的复杂BQ SQL代码更具模块性和可读性的方法。有什么方法可以做到这一点吗?

2 个答案:

答案 0 :(得分:3)

目前可用的选项是使用WITH Clause

  

WITH子句包含一个或多个已命名的子查询,其输出充当临时表,后续SELECT语句可以在任何子句或子参数中引用

我仍然认为User-Defined Functions是一个非常好的选择 JS和SQL UDF在BigQuery中可用,并且已知BigQuery团队正致力于推出permanent UDF即将推出

同时你可以将JS UDF的主体存储为js库,并使用OPTIONS部分在UDF中引用它。请参阅上述参考资料中的Including external libraries

答案 1 :(得分:0)

BigQuery支持持久的用户定义函数。要开始使用,请参见the documentation

例如,下面的CREATE FUNCTION语句创建一个函数来计算数组的中位数:

CREATE FUNCTION dataset.median(arr ANY TYPE) AS (
  (
    SELECT
      IF(
        MOD(ARRAY_LENGTH(arr), 2) = 0,
        (arr[OFFSET(DIV(ARRAY_LENGTH(arr), 2) - 1)] + arr[OFFSET(DIV(ARRAY_LENGTH(arr), 2))]) / 2,
        arr[OFFSET(DIV(ARRAY_LENGTH(arr), 2))]
      )
    FROM (SELECT ARRAY_AGG(x ORDER BY x) AS arr FROM UNNEST(arr) AS x)
  )
);

执行此语句后,可以在后续查询中引用它:

SELECT dataset.median([7, 1, 2, 10]) AS median;

您也可以在逻辑视图中引用该函数。请注意,当前您需要使用项目来限定对视图内部函数的引用,但是:

CREATE VIEW dataset.sampleview AS
SELECT x, `project-name`.dataset.median(array_column) AS median
FROM `project-name`.dataset.table