无法使用 google bigquery(标准)取消嵌套某些字段
Posted
技术标签:
【中文标题】无法使用 google bigquery(标准)取消嵌套某些字段【英文标题】:Unable to un-nest some fields using google bigquery (standard) 【发布时间】:2017-10-19 19:04:52 【问题描述】:我有一个嵌套表,我无法访问使用标准 google bigquery 的所有字段。
例如这个查询失败
SELECT *
FROM
(
SELECT
rev_info.user.id as player_id,
rev_info.purchase.total.currency as currency,
rev_info.purchase.total.amount as REV
,rev_info.purchase.virtual_items.items.sku as sku
FROM `gcs.rev`
)
WHERE currency = 'USD'
有错误
“错误:无法在 [9:59] 访问类型为 ARRAY> 的值的字段 sku”
然而
SELECT *
FROM
(
SELECT
rev_info.user.id as player_id,
rev_info.purchase.total.currency as currency,
rev_info.purchase.total.amount as REV
--,rev_info.purchase.virtual_items.items.sku as sku
FROM `gcs.rev`
)
WHERE currency = 'USD'
这个查询很好。
还要注意
SELECT
rev_info.purchase.virtual_items.items.sku as sku
FROM `gcs.rev`
失败并出现与上述相同的错误。
【问题讨论】:
您所说的“无法取消嵌套...”是什么意思?你还没试过!至少从您的问题中的查询来看是这样的! 您好,欢迎来到 ***!如果您收到的答案对您有任何帮助或解决了您的问题,请考虑接受并投票,因为这在此论坛中很重要:***.com/help/someone-answers 【参考方案1】:扩展 Elliott 的答案 - 我认为您首先需要 UNNEST,但随后您很可能需要汇总您的 sku
。否则你会得到相当冗余(扁平化)的输出
我觉得下面是您可能需要的 - 它适用于 BigQuery 标准 SQL
#standardSQL
SELECT
player_id,
currency,
REV,
STRING_AGG(sku) SKUs
FROM (
SELECT
rev_info.user.id AS player_id,
rev_info.purchase.total.currency AS currency,
rev_info.purchase.total.amount AS REV,
item.sku AS sku
FROM `gcs.rev` t,
UNNEST(t.rev_info.purchase.virtual_items.items) item
)
WHERE currency = 'USD'
GROUP BY 1, 2, 3
因此,所有 sku 将显示为给定 player_id 的列表,以及金额和货币
根据 Elliott 的评论/建议添加
#standardSQL
SELECT
rev_info.user.id AS player_id,
rev_info.purchase.total.currency AS currency,
rev_info.purchase.total.amount AS REV,
(SELECT STRING_AGG(item.sku)
FROM UNNEST(t.rev_info.purchase.virtual_items.items) item
) AS SKUs
FROM `gcs.rev` t,
WHERE currency = 'USD'
【讨论】:
或者ARRAY(SELECT sku FROM UNNEST(t.rev_info.purchase.virtual_items.items))
AS sku 来避免聚合(您也可以使用STRING_AGG
)。
完全同意。如果它是我的代码 - 我很可能会使用 (SELECT STRING_AGG(item.sku) FROM UNNEST(...) item) AS SKUs
之类的东西,而没有 GROUP BY
和没有 SELECT *
等。但是我在这里学到的关于在过去两年中每天回答的问题通常是 OP在许多情况下,尝试“简化”/混淆他们的代码,将他们的预期但真正重要的部分“小”留在外面,但通常他们不会转换/改变查询的结构。所以在这种情况下 - SELECT *
对我来说有点可疑,所以我尽量不改变内部查询【参考方案2】:
如果您的目标是为每个 items
数组元素获取一行,那么您可以在表和 rev_info.purchase.virtual_items.items
之间使用逗号(连接)运算符。例如,
SELECT *
FROM (
SELECT
rev_info.user.id as player_id,
rev_info.purchase.total.currency as currency,
rev_info.purchase.total.amount as REV,
item.sku as sku
FROM `gcs.rev` t,
t.rev_info.purchase.virtual_items.items item
)
WHERE currency = 'USD'
【讨论】:
谢谢,确实有效!但是,我很困惑为什么 SKU 是必要的,而不是 rev 或货币。特别是,我不明白为什么该标准显然正在执行的自动展平不直接执行此操作。 只有sku
才需要,因为包含它的字段 (items
) 是一个数组。对于currency
和amount
等其他字段路径,路径上没有数组。使用标准 SQL 时,没有“自动展平”;你必须明确地表达你的意图(比如在这种情况下使用逗号)。以上是关于无法使用 google bigquery(标准)取消嵌套某些字段的主要内容,如果未能解决你的问题,请参考以下文章
BigQuery 中用于 Google Analytics 数据的标准 SQL 还是旧版 SQL?
Google 标准 SQL UDF - 写入 BigQuery