将 bigquery 中的数组与空数组连接起来

Posted

技术标签:

【中文标题】将 bigquery 中的数组与空数组连接起来【英文标题】:Concatenating arrays in bigquery with empty arrays 【发布时间】:2018-12-10 22:41:27 【问题描述】:

我有一张如下所示的表格:

然后我尝试将 label1、label2、label3 聚合到一个数组中,用于每种类型的标签,然后,最后我想将所有非空标签放入一个组合数组中。所以我的查询看起来像这样

#standardSQL
WITH
table AS (
SELECT 'abc' id, 1 label1, 12 label2, 122 label3 UNION ALL
SELECT 'abc', 1, 12, 129 UNION ALL
SELECT 'xyz', 2, 23, NULL UNION ALL
SELECT 'xyz', 2, 24, NULL
),

each_label_agg AS (
 SELECT
 id,
 ARRAY_AGG(label1 IGNORE NULLS) AS label1_agg,
 ARRAY_AGG(label2 IGNORE NULLS) AS label2_agg,
 ARRAY_AGG(label3 IGNORE NULLS) AS label3_agg
FROM
table
GROUP BY
 id)
SELECT
 each_label_agg.*,
 ARRAY_CONCAT(each_label_agg.label1_agg, each_label_agg.label2_agg, 
 each_label_agg.label3_agg) AS combined_labels
FROM
 each_label_agg

输出如下:

但在输出中,我期望 combined_labels[2,2,23,24] 的 id xyz

ignore nulls 参数在array_concat 中不起作用。我猜想combined_labels 会因为label3 的空数组而出现格式错误。我怎样才能让xyz 的预期combined_labels 成为[2,2,23,24]

【问题讨论】:

【参考方案1】:
#standardSQL
WITH table AS (
  SELECT 'abc' id, 1 label1, 12 label2, 122 label3 UNION ALL
  SELECT 'abc', 1, 12, 129 UNION ALL
  SELECT 'xyz', 2, 23, NULL UNION ALL
  SELECT 'xyz', 2, 24, NULL
), each_label_agg AS (
 SELECT
   id,
   ARRAY_AGG(label1 IGNORE NULLS) AS label1_agg,
   ARRAY_AGG(label2 IGNORE NULLS) AS label2_agg,
   ARRAY_AGG(label3 IGNORE NULLS) AS label3_agg
  FROM table
  GROUP BY id
)
SELECT
  each_label_agg.*,
  ARRAY_CONCAT(
   IFNULL(each_label_agg.label1_agg, []), 
   IFNULL(each_label_agg.label2_agg, []),
   IFNULL(each_label_agg.label3_agg, [])
  ) AS combined_labels
FROM each_label_agg

【讨论】:

完全按照我的意愿工作!!再次感谢。但它的处理方式在我看来有点违反直觉。【参考方案2】:

此问题的原因是因为 BigQuery 具有 limitations 相对于 NULL 值,如果任何参数为 NULL,则数组生成将返回 NULL,如文档中的 here 所述。因此,将它们替换为空数组很方便(因为NULLs 和空数组在 BigQuery 中是两个不同的值)

【讨论】:

以上是关于将 bigquery 中的数组与空数组连接起来的主要内容,如果未能解决你的问题,请参考以下文章

如何将Mysql中的表与空表连接起来

标准 SQL 中的 BigQuery 连接数组

PostgreSQL unnest 与空数组

BigQuery concat 嵌套数组 json

如何在 Google BigQuery 中的数组中的元素上创建表连接

如何在bigquery中连接两个结构数组?