查询“记录”中的特定值
Posted
技术标签:
【中文标题】查询“记录”中的特定值【英文标题】:Querying specific values within a "RECORD" 【发布时间】:2020-12-23 08:19:52 【问题描述】:我最近一直在尝试直接查询我们的 Firebase Analytics 数据,因为 Firebase 仪表板只有一些非常基本的数据查看功能。
看起来我们可以直接在 BigQuery 中查询数据,但是 BigQuery 使用的数据库类型似乎是基于列的存储,并且具有与 mysql 等传统数据库不同的数据类型。
所以我最终完成了以下任务:
我曾尝试阅读 BigQuery 官方文档中的一些文档,例如这里:
https://cloud.google.com/bigquery/docs/reference/standard-sql/arrays
但它似乎是关于数组的,我不太了解文档,并且在 BigQuery 仪表板中它说这些列实际上不是一个数组,它们的类型是“记录”:
..我也没有在网上找到太多信息。
所以尝试仍然查询这个,因为我真的不知道该怎么做,我只是尝试了一些可能会让你们看起来很愚蠢的事情哈哈哈:
SELECT *
FROM `diningcity-2ad82.analytics_171798853.events_20201222`
WHERE event_params.string_value.screen_name = "Deal details"
LIMIT 1000;
所以我尝试使用“。”作为一种告诉 BigQuery“首先进入 event_params,然后进入 string_value 然后进入 screen_name,检查最终值”的方式。
但 BigQuery 不喜欢它:
Cannot access field string_value on a value with type ARRAY<STRUCT<key STRING, value STRUCT<string_value STRING, int_value INT64, float_value FLOAT64, ...>>> at [3:20]
那么谁能帮我找出我做错了什么以及正确的方法是什么?
作为参考,我也尝试过阅读本教程,但也没有真正理解????????:
https://www.simba.com/products/BigQuery/doc/JDBC_InstallGuide/content/jdbc/bq/features/records.htm
【问题讨论】:
【参考方案1】:BigQuery 表格式的含义是:
event_params
是一个结构数组——这就是“重复”的意思。
value
是该结构中的一个结构。
string_value
是该数组中的一个字符串字段。
我不知道为什么 BigQuery 在表描述中使用“记录”,而在文档中的其他任何地方都使用“结构”。
要访问数组,请使用unnest
。一种方法是在FROM
子句中。正如您所说的查询,这将是:
SELECT *
FROM `diningcity-2ad82.analytics_171798853.events_20201222` e CROSS JOIN
UNNEST(e.event_params) ep
WHERE v.screen_name = 'Deal details'
LIMIT 1000;
唯一的问题是screen_name
可能是“键”值而不是列/字段名称。所以,你真的想要:
SELECT *
FROM `diningcity-2ad82.analytics_171798853.events_20201222` e CROSS JOIN
UNNEST(e.event_params) ep
WHERE ep.key = 'screen_name' AND
ep.value.string_value = 'Deal details'
LIMIT 1000;
如果不想要结果集中的所有参数,可以使用:
SELECT * EXCEPT (event_params)
您也可以在子查询中执行此操作:
SELECT *
FROM `diningcity-2ad82.analytics_171798853.events_20201222` e
WHERE EXISTS (SELECT 1
FROM UNNEST(e.event_params) ep
WHERE ep.key = 'screen_name' AND
ep.value.string_value = 'Deal details'
LIMIT 1000;
如果您不想在一行可能有多个匹配项时将行数加倍,这很方便。
【讨论】:
嗨,我检查了你的答案,让我感到困惑的一件事是,Kyrylo 在 BigQuery 中的答案与你的非常相似,但有一个关键区别:从diningcity-2ad82 中选择 *。 analytics_171798853.events_20201222 as e, unnest(e.event_params) as ep WHERE ep.key = 'screen_name' AND ep.value.string_value = 'Deal details';在您的解决方案中,您还 CROSS JOIN "ep.value" 而不是只有 event_params,请问有什么区别?有吗? 实际上,如果我尝试您的第二个代码 sn-p,我在 BigQuery 编辑器中的 CROSS JOIN UNNEST(ep.value) AS v 部分出现错误:UNNEST 中引用的值必须是数组。 UNNEST 在 [2:124] 包含 STRUCT我尝试重新创建您在下面查询的 WITH 子句中拥有的数据。为了访问数组元素(重复),你必须UNNEST他们:
with data as (
select array<struct<value struct<string_value STRING, int_value INT64>, key STRING>>[struct(struct('1', 1), 'key1'), struct(struct('2', 2), 'key2')] as event_params
)
select unnested_array.value.string_value, unnested_array.value.int_value
from data, unnest(data.event_params) as unnested_array;
您的event_params
字段实际上是STRUCT
的ARRAY
。它的类型为RECORD
,其模式为REPEATED
,它们是来自旧版SQL 的命名,它等于ARRAY
的STRUCT
s。您可以找到标准 SQL 和旧版 SQL 数据类型的比较here。
您可以在文档中查看查询嵌套字段here 的一些示例。
【讨论】:
我使用 WITH 子句来模拟您在diningcity-2ad82.analytics_171798853.events_20201222
中拥有的数据,仅作为查询数据的示例。您不必使用 WITH 子句,而是在 FROM 子句中使用 diningcity-2ad82.analytics_171798853.events_20201222
而不是 data
,然后您将可以访问您查询的表中的所有列。重要的部分是使用UNNEST(data.event_params)
,在你的情况下应该是相似的。如果不明白请告诉我,以便我提供更好的答案
我试过:SELECT * FROM diningcity-2ad82.analytics_171798853.events_20201222
, UNNEST(event_params) WHERE event_params.string_value.screen_name = "交易详情" LIMIT 1000;还是同样的错误,我不明白
请试试这个:从diningcity-2ad82.analytics_171798853.events_20201222
中选择 * 作为 e,unnest(e.event_params) 作为 ep WHERE ep.key = 'screen_name' AND ep.value.string_value = 'Deal details';
我也不明白“WITH”是做什么的,我不明白我为什么需要这个?我想通过执行 SELECT * 来选择所有列,然后使用 WHERE 进行过滤
在documentation 中查找有关WITH
子句的更多信息。如果您使用我之前评论中的查询,则不再需要 WITH
子句。最初,我使用WITH
子句来模拟您的表的行为...以上是关于查询“记录”中的特定值的主要内容,如果未能解决你的问题,请参考以下文章