如何在 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中连接两个结构数组?

如何在 BigQuery 上展开数组以将列添加到现有表

如何在BigQuery中使用offset和ordinal从包含不同数据类型的数组中选择一个元素?

如何计算位于 BigQuery 表中的 json 数组中的对象数?

具有数组字段的 bigquery 表中的不同行

如何在 Bigquery¿ 中查询自动日期?