代码之家  ›  专栏  ›  技术社区  ›  Mohan

SQL UNNEST需要别名?

  •  0
  • Mohan  · 技术社区  · 7 年前

    我正在学习SQL,试图理解最不必要的东西。在具有以下架构的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://stackoverflow.com/a/51563922/1908650 例如,UNNEST在没有别名的情况下使用。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Mikhail Berlyant    7 年前

    我会尽力解释的
    将使用下面的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-简单选择*

    #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 (值分别为两个字段的结构) string_value 和int \u值),它们位于各个结构字段的名称之后,这些字段是由于未初始化的结构数组而获得的。
    要点:以开头的列 params

    所以,长话短说-我们可以直接引用它们 钥匙 价值 -例如

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

    希望上面的内容能帮助你与不熟悉的人友好相处:o)

    你可以阅读更多关于 UNNEST at文件 FROM clause -去那里,向下滚动一点,直到最不重要的部分

    如果您需要像下面的CTE中那样取消简单数组的命名,那么引用扁平元素的唯一方法就是通过alias

    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