BigQuery UNNEST 没有结果
BigQuery UNNEST No Results
我对嵌套数据的概念比较陌生,并试图了解在 BigQuery 中扁平化某些 GA 数据的正确方法 (https://support.google.com/analytics/answer/3437719?hl=en)。
现在给出一些上下文,对于每个访问者会话,我试图捕获查看过的产品 SKU 列表(详细视图),如果有交易,则为交易 ID。根据我的估计,在做了一些研究之后,最简单的方法如下所示,使用 LEFT JOINS 恢复所有内容:
SELECT fullVisitorId as uId, visitId as vId, h.transaction.transactionId as
trId, STRING_AGG(p.productSKU, "|") as skus
FROM
`test-bigquery.12345678.ga_sessions_*` t
LEFT JOIN UNNEST(hits) h
LEFT JOIN UNNEST(h.product) p
WHERE
_TABLE_SUFFIX = '20170709'
AND h.eCommerceAction.action_type = '2'
GROUP BY uId, vId, trId
但是,这似乎 return 零结果,其中 trId 不为空....
然后我尝试将上面的内容分成两个查询并加入。这似乎可行,并且 return 看起来合理的行数 (~1000) 其中 trId 不为空。
WITH skus AS
(SELECT fullVisitorId as uId, visitId as vId, STRING_AGG(p.productSKU, "|") as skus
FROM
`test-bigquery.12345678.ga_sessions_*` t
LEFT JOIN UNNEST(hits) h
LEFT JOIN UNNEST(h.product) p
WHERE
_TABLE_SUFFIX = '20170709'
AND h.eCommerceAction.action_type = '2'
GROUP BY uId, vId),
transactions AS
(SELECT fullVisitorId as uId_trans, visitId as vId_trans, h.transaction.transactionId as trId
FROM
`test-bigquery.12345678.ga_sessions_*` t
LEFT JOIN UNNEST(hits) h
WHERE
_TABLE_SUFFIX = '20170709'
AND h.transaction.transactionId IS NOT NULL
GROUP BY uId_trans, vId_trans, trId)
SELECT skus.uId, skus.vId, transactions.trId, skus.skus
FROM skus
LEFT JOIN transactions ON transactions.vId_trans = skus.vId AND transactions.uId_trans = skus.uId
如果有人能解释为什么两者没有给出相同的答案,并希望让我能够在未来参与各种嵌套乐趣……谢谢!
你犯的错误发生在这一行:
AND h.eCommerceAction.action_type = '2'
如果您检查 ga sessions schema 字段 action_type
,您会看到当客户刚刚看到产品时它的值为“2”,而当交易发生时它的值为“6” .因此,如果您仅过滤掉等于“2”的操作,您将无法获得值为“6”的交易。
在您的第二个查询中,请注意您对 transactions
的查询不再过滤掉操作为“2”的位置,而是过滤掉 trasactionId
不为空的位置,因此您现在可以成功检索这些行.
仍然有一些方法可以大大优化您的查询,例如:
SELECT
fullvisitorid,
visitid,
ARRAY(SELECT STRUCT(prods.productsku AS sku, MAX(IF(hits.ecommerceaction.action_type = '6', hits.transaction.transactionID, NULL)) AS transactionID) FROM UNNEST(hits) hits, UNNEST(hits.product) prods WHERE hits.ecommerceaction.action_type IN ('2', '6') GROUP BY prods.productsku) result
FROM `test-bigquery.12345678.ga_sessions_*`
WHERE TRUE
AND _TABLE_SUFFIX = '20170709'
AND EXISTS(SELECT 1 FROM UNNEST(hits) hits WHERE hits.ecommerceaction.action_type IN ('2', '6'))
LIMIT 1000
此查询产生的结果与您的相同,但更简洁且性能更高(它避免了不必要的 JOIN
s 和 UNNEST
s 操作,并充分利用了 ARRAY 和 STRUCT数据中的结构)。
我强烈建议您学习如何将这些技术用于嵌套数据,因为您将能够在几秒钟内查询数百兆。这些是我在数据集中得到的结果:
它在 15 秒内处理了超过 500Gbs。
我对嵌套数据的概念比较陌生,并试图了解在 BigQuery 中扁平化某些 GA 数据的正确方法 (https://support.google.com/analytics/answer/3437719?hl=en)。
现在给出一些上下文,对于每个访问者会话,我试图捕获查看过的产品 SKU 列表(详细视图),如果有交易,则为交易 ID。根据我的估计,在做了一些研究之后,最简单的方法如下所示,使用 LEFT JOINS 恢复所有内容:
SELECT fullVisitorId as uId, visitId as vId, h.transaction.transactionId as
trId, STRING_AGG(p.productSKU, "|") as skus
FROM
`test-bigquery.12345678.ga_sessions_*` t
LEFT JOIN UNNEST(hits) h
LEFT JOIN UNNEST(h.product) p
WHERE
_TABLE_SUFFIX = '20170709'
AND h.eCommerceAction.action_type = '2'
GROUP BY uId, vId, trId
但是,这似乎 return 零结果,其中 trId 不为空....
然后我尝试将上面的内容分成两个查询并加入。这似乎可行,并且 return 看起来合理的行数 (~1000) 其中 trId 不为空。
WITH skus AS
(SELECT fullVisitorId as uId, visitId as vId, STRING_AGG(p.productSKU, "|") as skus
FROM
`test-bigquery.12345678.ga_sessions_*` t
LEFT JOIN UNNEST(hits) h
LEFT JOIN UNNEST(h.product) p
WHERE
_TABLE_SUFFIX = '20170709'
AND h.eCommerceAction.action_type = '2'
GROUP BY uId, vId),
transactions AS
(SELECT fullVisitorId as uId_trans, visitId as vId_trans, h.transaction.transactionId as trId
FROM
`test-bigquery.12345678.ga_sessions_*` t
LEFT JOIN UNNEST(hits) h
WHERE
_TABLE_SUFFIX = '20170709'
AND h.transaction.transactionId IS NOT NULL
GROUP BY uId_trans, vId_trans, trId)
SELECT skus.uId, skus.vId, transactions.trId, skus.skus
FROM skus
LEFT JOIN transactions ON transactions.vId_trans = skus.vId AND transactions.uId_trans = skus.uId
如果有人能解释为什么两者没有给出相同的答案,并希望让我能够在未来参与各种嵌套乐趣……谢谢!
你犯的错误发生在这一行:
AND h.eCommerceAction.action_type = '2'
如果您检查 ga sessions schema 字段 action_type
,您会看到当客户刚刚看到产品时它的值为“2”,而当交易发生时它的值为“6” .因此,如果您仅过滤掉等于“2”的操作,您将无法获得值为“6”的交易。
在您的第二个查询中,请注意您对 transactions
的查询不再过滤掉操作为“2”的位置,而是过滤掉 trasactionId
不为空的位置,因此您现在可以成功检索这些行.
仍然有一些方法可以大大优化您的查询,例如:
SELECT
fullvisitorid,
visitid,
ARRAY(SELECT STRUCT(prods.productsku AS sku, MAX(IF(hits.ecommerceaction.action_type = '6', hits.transaction.transactionID, NULL)) AS transactionID) FROM UNNEST(hits) hits, UNNEST(hits.product) prods WHERE hits.ecommerceaction.action_type IN ('2', '6') GROUP BY prods.productsku) result
FROM `test-bigquery.12345678.ga_sessions_*`
WHERE TRUE
AND _TABLE_SUFFIX = '20170709'
AND EXISTS(SELECT 1 FROM UNNEST(hits) hits WHERE hits.ecommerceaction.action_type IN ('2', '6'))
LIMIT 1000
此查询产生的结果与您的相同,但更简洁且性能更高(它避免了不必要的 JOIN
s 和 UNNEST
s 操作,并充分利用了 ARRAY 和 STRUCT数据中的结构)。
我强烈建议您学习如何将这些技术用于嵌套数据,因为您将能够在几秒钟内查询数百兆。这些是我在数据集中得到的结果:
它在 15 秒内处理了超过 500Gbs。