我正在学习SQL,并试图了解UNNEST。在具有以下架构的FireBase事件表上:
event_params RECORD REPEATED
event_params. key STRING NULLABLE
event_params. value RECORD NULLABLE
event_params.value. string_value STRING NULLABLE
event_params.value. int_value INTEGER NULLABLE
这有效:
SELECT params.key, params.value.string_value, params.value.int_value
FROM `...events_20181021`,
UNNEST(event_params) as params
我跑步的时候
SELECT *
FROM `...events_20181021`,
UNNEST(event_params)
我看到event_params.key, event_params.value.string_value, event_params.value.int_value
之类的列(在BigQuery中)。但是当我尝试
SELECT event_params.key, event_params.value.string_value, event_params.value.int_value
FROM `...events_20181021`,
UNNEST(event_params)
失败。为什么?
编辑:有关未使用别名的UNNEST的示例,请参见https://stackoverflow.com/a/51563922/1908650。
答案 0 :(得分:2)
我会尽力解释
将在下面的示例中使用CTE
WITH `table` AS (
SELECT 1 id, [STRUCT<key STRING, value STRUCT<string_value STRING, int_value INT64>>('a', ('1',1)),('b', ('2',2)),('c', ('3',3))] params UNION ALL
SELECT 2, [STRUCT<key STRING, value STRUCT<string_value STRING, int_value INT64>>('x', ('666', 666)),('y', ('777',777))]
)
示例1-简单的SELECT *
#standardSQL
SELECT *
FROM `table`
这将在[明显预期的]输出以下
Row id params.key params.value.string_value params.value.int_value
1 1 a 1 1
b 2 2
c 3 3
2 2 x 666 666
y 777 777
示例2-不带别名的UNNEST
#standardSQL
SELECT *
FROM `table`, UNNEST(params)
结果将是
Row id params.key params.value.string_value params.value.int_value key value.string_value value.int_value
1 1 a 1 1 a 1 1
b 2 2
c 3 3
2 1 a 1 1 b 2 2
b 2 2
c 3 3
3 1 a 1 1 c 3 3
b 2 2
c 3 3
4 2 x 666 666 x 666 666
y 777 777
5 2 x 666 666 y 777 777
y 777 777
现在您可以看到另外两个名为key
和value
的列(值为STRUCT,分别具有两个字段string_value
和int_value),分别位于对应的STRUCT字段的名称之后,嵌套结构的结果。
重要说明:以params
开头的列实际上是REPEATED RECORD的一部分,无法直接访问,而那些由UNNEST'ing产生的字段-可以直接引用(除非其中一些字段本身是数组)在这种情况下,将需要第二个UNNEST)
所以,长话短说-我们可以直接将它们分别引用为key
和value
-例如
示例3-引用“继承的”字段名称
#standardSQL
SELECT id, key, value
FROM `table`, UNNEST(params)
Row id key value.string_value value.int_value
1 1 a 1 1
2 1 b 2 2
3 1 c 3 3
4 2 x 666 666
5 2 y 777 777
示例4-使用别名的UNNEST
很明显,您可以为UNNEST提供别名以避免潜在的歧义-如果存在另一个名为(例如)“ key”的字段,那么您希望能够解决这个问题
#standardSQL
SELECT id AS key, param.key AS param_key, value
FROM `table`, UNNEST(params) param
结果为
Row key param_key value.string_value value.int_value
1 1 a 1 1
2 1 b 2 2
3 1 c 3 3
4 2 x 666 666
5 2 y 777 777
希望,上面的内容将帮助您与UNNEST变得友好:o)
您可以在FROM clause的文档中了解有关UNNEST
的更多信息-转到此处并向下滚动直到UNNEST部分
示例5-需要别名的情况
如果您需要像下面的CTE中那样取消简单数组,则唯一引用扁平化元素的方法是仅通过别名
WITH `project.dataset.table` AS (
SELECT 1 id, [1,2,3] params UNION ALL
SELECT 2, [666,777]
)
例如
#standardSQL
SELECT id, param
FROM `project.dataset.table`, UNNEST(params) param
WHERE NOT param IN (2,777)
有结果
Row id param
1 1 1
2 1 3
3 2 666