我们有一个表,该表包含2个类型为“ struct”的顶级列-一个是“ before”和一个“ after”图像。结构模式很简单-嵌套,数组的深度可变。都是通过复制发送给我们的,因此架构始终是相同的(但是这些架构当然可以在某个时刻进行更新,但始终可以一起更新)
目标是针对两个输入结构,仅返回已更改的字段,然后返回2个之前和之后的结构'diffs'-本质上是复制源产生的更改的'delta'diff。我们知道有些事情已经改变,但是自从我们获得完整的图像前后之后,什么都没有改变。这些原始数据将进入BQ,然后从那里进行处理,但需要确定更精细的变化以进行高阶BQ处理。
表架构非常宽(1000个叶字段),并且填充的数据相当空闲(因此快照的两侧都将出现大量的空值)-因此在执行时需要尽可能地提高性能超过一千万行。
为了最大的灵活性,所有东西都可以为空。
所以变化可能看起来像:
数组:
对结构数组的递归使用,是否可以简化排序?
不可能。
我还没有尝试过,因为看起来真的很困难,所以我希望社区的off子对此有所支持。我觉得数组可能是困难的部分。也许有一种简单的方法,也许我不使用Python,甚至使用JOSN工具进行一些JSON转换和比较?感觉这也将是BQ内置的超酷功能,因此,如果可以正常使用,将为其添加功能请求。
Id喜欢拥有可重用的SQL UDF(我们拥有SQL技能,但不是python,尽管如果使用python更容易,那没关系),现在有了持久SQL UDF的新功能,这似乎是提出和测试的最佳时机功能!
sql def struct_diff(在Struct之前,在Struct之后)
(beforeChange,afterChange)-签名类型但可以接受建议吗?
答案 0 :(得分:0)
获得一段可重用的代码似乎真的很困难。由于当前不支持SQL UDF的递归函数,因此不能对嵌套结构使用递归方法。
尽管如此,您可能可以获取一些特定的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))
);
您可以使用UNNEST
到work with arrays,最终的SQL UDF确实取决于您的数据。
正如@rtenha所建议的那样,Python可能更容易处理这个问题。
最后,我使用JavaScript UDF进行了一些测试,结果基本相同,即使不比SQL UDF差。
控制台允许对函数进行递归定义,但是在执行期间它将失败。另外,签名上的javascript doesn't allow the ANY TYPE
数据类型,因此您必须定义整个STRUCT定义,或使用类似的解决方法,例如将TO_JSON_STRING
应用于结构,以将其作为字符串传递。