如何在没有交叉产品的情况下从 BigQuery 中的两列中取消嵌套两个列表,作为单独的行

Posted

技术标签:

【中文标题】如何在没有交叉产品的情况下从 BigQuery 中的两列中取消嵌套两个列表,作为单独的行【英文标题】:How to unnest two lists from two columns in BigQuery without cross product, as individual rows 【发布时间】:2020-01-29 00:47:54 【问题描述】:

我在 BigQuery 中有一个表,它有两列,每列包含一个数组。对于给定的行,两列将包含相同长度的数组,但该长度可能因行而异:

WITH tbl AS (
select ['a','b','c'] AS one, [1,2,3] as two
union all
select ['a','x'] AS two, [10,20] as two
)
select * from tbl

所以表格看起来像:

row | one     | two
-----------------------
1   | [a,b,c] | [1,2,3]
2   | [a,x]   | [10,20]

我想以这样一种方式取消嵌套,即新表中的每一行都将具有来自 column1 的数组元素和来自 column2 的相应元素。因此,从上表中,我希望得到:

row | one | two
---------
1   | a   | 1
2   | b   | 2
3   | c   | 3
4   | a   | 10
5   | x   | 20

任何帮助将不胜感激!谢谢!

【问题讨论】:

【参考方案1】:

以下是 BigQuery 标准 SQL

#standardSQL
SELECT z.*
FROM `project.dataset.table` t,
UNNEST(ARRAY(
  SELECT AS STRUCT one, two
  FROM UNNEST(one) one WITH OFFSET
  JOIN UNNEST(two) two WITH OFFSET
  USING(OFFSET)
  )
) z

您可以使用您问题中的示例数据进行测试,使用上面的内容 - 结果将是

Row one two  
1   a   1    
2   b   2    
3   c   3    
4   a   10   
5   x   20     

我不完全理解语法,你能解释一下吗?

解释:

步骤 1

为下表中的每一行计算数组

ARRAY(
  SELECT AS STRUCT one, two
  FROM UNNEST(one) one WITH OFFSET
  JOIN UNNEST(two) two WITH OFFSET
  USING(OFFSET)
)  

此数组的元素是具有来自两列的各自值的结构 - 它们通过在初始数组中的位置加入(偏移)来相互匹配

第二步

然后这个数组得到 UNNEST'ed 并与表中的相应行交叉 JOIN'ed - 实际上整行被忽略,只有那个结构 (z) 被带入输出

第三步

最后不是输出结构而是作为单独的列 - 使用z.*

希望这会有所帮助:o)

【讨论】:

谢谢米哈伊尔,效果很好。但我不完全理解语法,你能解释一下吗?谢谢!

以上是关于如何在没有交叉产品的情况下从 BigQuery 中的两列中取消嵌套两个列表,作为单独的行的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在没有 OAuth2 身份验证对话框的情况下从 Google App-Engine (python) 连接和查询 BigQuery 表?

在不使用表格的情况下从 BigQuery 中的 csv 文件中检索数据

在bigquery中交叉应用MSSQL运算符等效

如何在没有 \n 的情况下从 txt 中获取特定行(Python)

如何在没有终端提示的情况下从 IPython 会话中复制

如何在没有动画的情况下从集合视图中删除项目?