繁体   English   中英

在 BigQuery 表中按行有效地外部连接两个数组列

[英]Efficiently outer join two array columns row-wise in BigQuery table

我将首先 state 尽可能简单地提出问题,然后详细说明并举例说明。

没有上下文的简洁问题

我有一个表,其中的行包含 arrays 列。 我需要外连接其中一些对的元素,计算一些变量,然后将结果聚合回一个新数组。 我目前使用的模式是:

  1. 取消要连接的对中的每一列(交叉连接到行的 PK)
  2. 在 PK 上完全外连接两者并计算所需字段
  3. 按 PK 分组以返回具有汇总结果的数组列的单行

有没有办法在没有多次取消嵌套和分组的情况下做到这一点?

更多上下文和示例

我有一个表,它表示对由多个子记录组成的实体的编辑。 每行代表一个实体。 before有一列包含编辑前的记录,之后的另一列包含编辑after的记录。

我的目标是 label 每个子记录恰好具有四种有效编辑类型之一:

  1. DELETE - 记录存在于before但不存在于after
  2. ADD - 记录存在于after但不存在于before
  3. 编辑 - beforeafter都存在记录,但任何字段都已更改
  4. NONE - beforeafter都存在记录,并且没有更改任何字段

每个子记录值都由其 ID 和所有字段的 hash 表示。 我创建了一些假数据,并在下面提供了我的初始实现。 这行得通,但它似乎很迂回。

WITH source_data AS (
  SELECT
    1 AS pkField,
    [
      STRUCT(1 AS id, 1 AS fieldHash),
      STRUCT(2 AS id, 2 AS fieldHash),
      STRUCT(3 AS id, 3 AS fieldHash)
    ] AS before,
    [
      STRUCT(1 AS id, 1 AS fieldHash),
      STRUCT(2 AS id, 0 AS fieldHash),  -- record 2 edited
      -- record 3 deleted
      STRUCT(4 AS id, 4 AS fieldHash), -- record 4 added
      STRUCT(5 AS id, 5 AS fieldHash)  -- record 5 added
    ] AS after
)
SELECT
  pkField,
  ARRAY_AGG(STRUCT(
    id,
    CASE
      WHEN beforeHash IS NULL THEN "ADD"
      WHEN afterHash IS NULL THEN "DELETE"
      WHEN beforeHash <> afterHash THEN "EDIT"
      ELSE "NONE"
    END AS editType
  )) AS edits
FROM (
  SELECT pkField, id, fieldHash AS beforeHash
  FROM source_data
  CROSS JOIN UNNEST(source_data.before)
)
FULL OUTER JOIN (
  SELECT pkField, id, fieldHash AS afterHash
  FROM source_data
  CROSS JOIN UNNEST(source_data.after)
)
USING (pkField, id)
GROUP BY pkField

有没有更简单和/或更有效的方法来做到这一点? 也许可以避免多次取消嵌套和分组?

我认为,您所拥有的已经是简单有效的方法!
同时,您可以考虑以下优化版本

select pkField, 
  array(select struct(
      id, case
      when b.fieldHash is null then 'ADD'
      when a.fieldHash is null then 'DELETE'
      when b.fieldHash != a.fieldHash then 'EDIT'
      else 'NONE'
      end as editType
    ) edits
    from (select id, fieldHash from t.before) b
    full outer join (select id, fieldHash from t.after) a
    using(id)
  ) edits
from source_data t

如果应用于您问题中的示例数据 - output 是

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM