SQL UNNEST是否需要别名?

时间:2018-10-23 16:14:43

标签: sql google-bigquery

我正在学习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

1 个答案:

答案 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              

现在您可以看到另外两个名为keyvalue的列(值为STRUCT,分别具有两个字段string_value和int_value),分别位于对应的STRUCT字段的名称之后,嵌套结构的结果。
重要说明:以params开头的列实际上是REPEATED RECORD的一部分,无法直接访问,而那些由UNNEST'ing产生的字段-可以直接引用(除非其中一些字段本身是数组)在这种情况下,将需要第二个UNNEST)

所以,长话短说-我们可以直接将它们分别引用为keyvalue-例如

  

示例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