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 在重复字段上连接表的主要内容,如果未能解决你的问题,请参考以下文章