如何在 bigquery 中查询数组?
Posted
技术标签:
【中文标题】如何在 bigquery 中查询数组?【英文标题】:How to query arrays in bigquery? 【发布时间】:2017-07-18 18:03:49 【问题描述】:bigquery 中的模式 领域:项目 类型:字符串
项目字段表中的值存储为字符串
"data": ["id": "1234", "plan": "sub_id": "567", "metadata": "currentlySelling": "true", "custom_attributes": "\"shipping\": true,\"productLimit\":10", "Features": "[\"10 products\", \"Online support\"]", "name": "Personal", "object": "plan", "quantity": 1], "has_more": false
两个问题 1) 我如何在数组中查询,例如:在哪里发货或其中一项功能是“在线支持” 2) 我必须将数据存储为字符串的原因是因为“custom_attributes”值可能会改变。当嵌套键之一的值可以更改时,是否有更好的方法在 bigquery 中存储数据?
【问题讨论】:
您应该明确表的实际架构!还有 - 到目前为止你尝试过什么?请编辑您的问题以显示您遇到问题的代码的Minimal, Complete, and Verifiable example,然后我们可以尝试帮助解决具体问题。你也可以阅读How to Ask。 【参考方案1】:您的查询将是这样的:
#standardSQL
SELECT game
FROM YourTable
WHERE EXISTS (SELECT 1 FROM UNNEST(participant) WHERE name = 'sam');
这将返回'sam'
参与的所有游戏。这是一个独立的示例:
#standardSQL
WITH YourTable AS (
SELECT 'A' AS game, ARRAY<STRUCT<name STRING, age INT64>>[('sam', 12), ('tony', 12), ('julia', 12)] AS participant UNION ALL
SELECT 'B', ARRAY<STRUCT<name STRING, age INT64>>[('sam', 12), ('max', 12), ('jacob', 12)] UNION ALL
SELECT 'C', ARRAY<STRUCT<name STRING, age INT64>>[('sam', 12), ('max', 12), ('julia', 12)]
)
SELECT game
FROM YourTable
WHERE EXISTS (SELECT 1 FROM UNNEST(participant) WHERE name = 'sam');
如果您想将数据转置为每个参与者都有一个列,您可以使用如下查询:
#standardSQL
CREATE TEMP FUNCTION WasParticipant(
p_name STRING, participant ARRAY<STRUCT<name STRING, age INT64>>) AS (
EXISTS(SELECT 1 FROM UNNEST(participant) WHERE name = p_name)
);
WITH YourTable AS (
SELECT 'A' AS game, ARRAY<STRUCT<name STRING, age INT64>>[('sam', 12), ('tony', 12), ('julia', 12)] AS participant UNION ALL
SELECT 'B', ARRAY<STRUCT<name STRING, age INT64>>[('sam', 12), ('max', 12), ('jacob', 12)] UNION ALL
SELECT 'C', ARRAY<STRUCT<name STRING, age INT64>>[('sam', 12), ('max', 12), ('julia', 12)]
)
SELECT
ARRAY_AGG(IF(WasParticipant('sam', participant), game, NULL) IGNORE NULLS) AS sams_games,
ARRAY_AGG(IF(WasParticipant('tony', participant), game, NULL) IGNORE NULLS) AS tonys_games,
ARRAY_AGG(IF(WasParticipant('julia', participant), game, NULL) IGNORE NULLS) AS julias_games,
ARRAY_AGG(IF(WasParticipant('max', participant), game, NULL) IGNORE NULLS) AS maxs_games
FROM YourTable;
这将返回一个数组,其中包含为每个参与者玩的游戏。
【讨论】:
数据以字符串形式存储。如果数据被重复存储,上述方法将起作用。Error: Values referenced in UNNEST must be arrays. UNNEST contains expression of type STRING at [2:36]
所以participant
是一个看起来像'["name":"sam","age": 12,"name":"tony","age": 12,"name":"julia","age": 12]
' 的字符串?最好让您的表架构与数据匹配,并为participant
使用重复记录字段。
Elliot,我想做你所说的,将模式与数据匹配。我无法做到这一点的原因是因为我有一些字典项目,例如:custom_attributes 可以更改,所以我最终将所有内容都粘贴到字符串列中,因此我不必担心将新的键/值对添加到自定义属性中.我将按照 Mikhail 的建议发布我的表架构和实际数据。以上是关于如何在 bigquery 中查询数组?的主要内容,如果未能解决你的问题,请参考以下文章
如何在BigQuery中使用offset和ordinal从包含不同数据类型的数组中选择一个元素?