SQL UDF-结构差异

时间:2019-07-10 08:40:14

标签: google-bigquery

我们有一个表,该表包含2个类型为“ struct”的顶级列-一个是“ before”和一个“ after”图像。结构模式很简单-嵌套,数组的深度可变。都是通过复制发送给我们的,因此架构始终是相同的(但是这些架构当然可以在某个时刻进行更新,但始终可以一起更新)

目标是针对两个输入结构,仅返回已更改的字段,然后返回2个之前和之后的结构'diffs'-本质上是复制源产生的更改的'delta'diff。我们知道有些事情已经改变,但是自从我们获得完整的图像前后之后,什么都没有改变。这些原始数据将进入BQ,然后从那里进行处理,但需要确定更精细的变化以进行高阶BQ处理。

表架构非常宽(1000个叶字段),并且填充的数据相当空闲(因此快照的两侧都将出现大量的空值)-因此在执行时需要尽可能地提高性能超过一千万行。

为了最大的灵活性,所有东西都可以为空。

所以变化可能看起来像:

  • 空->值
  • 值->空
  • valueA-> valueB

数组:

对结构数组的递归使用,是否可以简化排序?

不可能。

我还没有尝试过,因为看起来真的很困难,所以我希望社区的off子对此有所支持。我觉得数组可能是困难的部分。也许有一种简单的方法,也许我不使用Python,甚至使用JOSN工具进行一些JSON转换和比较?感觉这也将是BQ内置的超酷功能,因此,如果可以正常使用,将为其添加功能请求。

Id喜欢拥有可重用的SQL UDF(我们拥有SQL技能,但不是python,尽管如果使用python更容易,那没关系),现在有了持久SQL UDF的新功能,这似乎是提出和测试的最佳时机功能!

sql def struct_diff(在Struct之前,在Struct之后)

(beforeChange,afterChange)-签名类型但可以接受建议吗?

1 个答案:

答案 0 :(得分:0)

获得一段可重用的代码似乎真的很困难。由于当前不支持SQL UDF的递归函数,因此不能对嵌套结构使用递归方法。

Invalid recursive definition

尽管如此,您可能可以获取一些特定的SQL UDF函数,具体取决于您的数组和结构结构。您可以使用这种方法来比较结构。

CREATE TEMP FUNCTION final_compare(s1 ANY TYPE, s2 ANY TYPE) AS (
  STRUCT(s1 as prev, s2 as cur)
);

CREATE TEMP FUNCTION compare(s1 ANY TYPE, s2 ANY TYPE) AS (
  STRUCT(final_compare(s1.structA, s2.structA))  
);

您可以使用UNNESTwork with arrays,最终的SQL UDF确实取决于您的数据。

正如@rtenha所建议的那样,Python可能更容易处理这个问题。

最后,我使用JavaScript UDF进行了一些测试,结果基本相同,即使不比SQL UDF差。

控制台允许对函数进行递归定义,但是在执行期间它将失败。另外,签名上的javascript doesn't allow the ANY TYPE数据类型,因此您必须定义整个STRUCT定义,或使用类似的解决方法,例如将TO_JSON_STRING应用于结构,以将其作为字符串传递。