SQL UNNEST 需要别名?

Posted

技术标签:

【中文标题】SQL UNNEST 需要别名?【英文标题】:SQL UNNEST requires alias? 【发布时间】:2018-10-23 16:14:42 【问题描述】:

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

失败了。为什么?

编辑:请参阅https://***.com/a/51563922/1908650,了解不使用别名的 UNNEST 示例。

【问题讨论】:

unnest() 需要别名。否则,如何引用selectonwhere 中的未嵌套值? @GordonLinoff 这有点道理——但为什么我在第二个查询中看到像 event_params.key 这样的列名? 。 .这些是结构参考。您应该按照 BQ 教程来熟悉它。 正如您从我的回答中看到的那样 - 不需要别名 - 除非您真的需要它 - 请参阅回答 【参考方案1】:

我会尽力解释 将在我的示例中使用低于 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),它们位于由于 UNNEST'ing ARRAY 而获得的各个 STRUCT 字段的名称之后结构。 重要提示:以params 开头的列实际上是 REPEATED RECORD 的一部分,不能直接访问,而那些作为 UNNEST 的结果的字段 - 可以直接引用(除非其中一些本身是数组,其中将需要第二个 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 那样 UNNEST 简单数组,引用展平元素的唯一方法是仅通过别名

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  

【讨论】:

添加了Example #5

以上是关于SQL UNNEST 需要别名?的主要内容,如果未能解决你的问题,请参考以下文章

带有 unnest 的嵌套 SQL 评估问题

在 Linux 中,不同的 SQL 不适用于 UNNEST

在 Linux 中,不同的 SQL 不适用于 UNNEST

UNNEST 就是将sql 里面的数据展开

SQL 'FROM UNNEST' 的语义是啥?

如何在 BigQuery SQL 中使用 UNNEST 和 SPLIT 避免重复?