BigQuery 在重复字段上连接表

Posted

技术标签:

【中文标题】BigQuery 在重复字段上连接表【英文标题】:BigQuery joining tables on repeated fields 【发布时间】:2018-12-04 17:00:19 【问题描述】:

我有一个表,其中包含 id 作为单列和嵌套的多列。

1)

一个更好理解的示例模式:

id - 字符串,

childrenNames - 重复的字符串,

animalNames - 重复的字符串,

另一个表只包含单列

2)

一个更好理解的示例模式:

childrenName - 字符串,

动物名 - 字符串

我需要知道表 2) 中不在表 1) 中的所有记录 所以 childrenName 和 animalName 都需要同时属于一个用户。

我可以补充一点,我尝试为表 2 中的每一列分别选择表 1) 中的 'IN' 列表的值,但如果它返回任何行,也可能意味着两者都属于到两个不同的 id(或更多)。

示例行表1)

id:1234,

childrenNames : ['Ana', 'Frank'],

animalNames : ['Rex', 'Max'],

示例行表 2)

一)

childrenName : '安娜',

动物名:'奥兹'

B)

childrenName : '弗兰克',

动物名称:'雷克斯'

对于上述示例,我应该从表 2) 中获取行 A),因为“Ozzy”不属于 id 1234(假设我们在表 1 中没有更多记录)

有人知道如何使用 BigQuery SQL(标准或旧版)解决此类问题吗?

【问题讨论】:

你应该提供你的数据示例! 谢谢!我刚刚添加了它。 【参考方案1】:

以下是 BigQuery 标准 SQL

#standardSQL
SELECT childrenName, animalName, ARRAY_AGG(DISTINCT id) users
FROM `project.dataset.table2`
CROSS JOIN `project.dataset.table1`
WHERE (SELECT COUNT(1) FROM UNNEST(childrenNames) cn WHERE cn = childrenName) > 0
AND (SELECT COUNT(1) FROM UNNEST(animalNames) an WHERE an = animalName) > 0
GROUP BY childrenName, animalName

您可以针对您的问题使用数据示例进行测试、使用上述操作

#standardSQL
WITH `project.dataset.table1` AS (
  SELECT '1' id, ['Ana', 'Frank'] childrenNames,  ['Rex', 'Max'] animalNames 
), `project.dataset.table2` AS (
  SELECT 'Ana' childrenName, 'Ozzy' animalName UNION ALL
  SELECT 'Frank', 'Rex'
)
SELECT childrenName, animalName, ARRAY_AGG(DISTINCT id) users
FROM `project.dataset.table2`
CROSS JOIN `project.dataset.table1`
WHERE (SELECT COUNT(1) FROM UNNEST(childrenNames) cn WHERE cn = childrenName) > 0
AND (SELECT COUNT(1) FROM UNNEST(animalNames) an WHERE an = animalName) > 0
GROUP BY childrenName, animalName

结果

Row childrenName    animalName  users    
1   Frank           Rex         1     

注意:输出中的字段users 是一个重复的字符串/数组,由具有搜索对的用户列表组成

上面不那么冗长的变体将是

#standardSQL
SELECT childrenName, animalName, ARRAY_AGG(DISTINCT id) users
FROM `project.dataset.table2`
CROSS JOIN `project.dataset.table1`
WHERE childrenName IN UNNEST(childrenNames)
AND animalName IN UNNEST(animalNames)
GROUP BY childrenName, animalName

结果完全相同

所以,显然 - 使用第二个 :o)

... 表 1) 有 500 万条记录,表 2) 200k - 因此Query exceeded resource limits

试试下面的版本

#standardSQL
WITH flatten_table1 AS (
  SELECT id, childrenName, animalName
  FROM `project.dataset.table1`, 
  UNNEST(childrenNames) childrenName,
  UNNEST(animalNames) animalName
)
SELECT childrenName, animalName, id
FROM `project.dataset.table2`
JOIN flatten_table1
USING(childrenName, animalName) 

【讨论】:

第二个查询是否有任何优化可能?我得到'错误:查询超出资源限制。使用了 112320.34437458635 CPU 秒,并且在运行应用于我的数据的查询时,此查询必须使用少于 46000.0 CPU 秒。 从删除 ARRAY_AGG(DISTINCT id) 开始,因为首先删除 ARRAY_AGG 中的 DISTINCT 是额外的,或者可能更好 删除那块后我也遇到了这个错误。 什么错误和什么?还让我们了解您的真实数据是什么 - 数量方面 - 正如您提到的问题 - (lets suppose we do not have more records in table 1 上述错误所以''错误:查询超出资源限制。使用了 112320.34437458635 CPU 秒,并且此查询必须使用少于 46000.0 CPU 秒。我的意思是上一个查询中的“ARRAY_AGG(DISTINCT id)”。表 1) 有 500 万条记录,表 2) 200k

以上是关于BigQuery 在重复字段上连接表的主要内容,如果未能解决你的问题,请参考以下文章

在 BigQuery 中展平嵌套层次结构

重复字段的 BigQuery 记录

如何连接 BigQuery 已分配不同类型的整数字段?

查询 Bigquery 重复字段

从Google BigQuery中的嵌套表中删除重复项

在 BIGQUERY 上使用 UNNEST 左连接