创建列类型为 RECORD 的表

Posted

技术标签:

【中文标题】创建列类型为 RECORD 的表【英文标题】:create a table with a column type RECORD 【发布时间】:2016-01-25 15:35:39 【问题描述】:

我正在使用大查询,我想创建一个使用“记录”类型列填充表的作业。 数据将由查询填充 - 那么我如何编写返回“记录”类型列的查询。

谢谢!

【问题讨论】:

您的费率很低。对 SO 很重要,您必须使用已发布答案左侧、投票下方的勾号来标记已接受的答案。这将提高您的费率。通过访问此链接了解其工作原理:meta.***.com/questions/5234/… 【参考方案1】:

Pentium10 提出的某种选项在 GBQ UI 或 API Explorer 中从未对我有用。 我可能遗漏了什么

同时,我发现的解决方法如下例所示

SELECT location.state, location.city FROM JS(
  (      // input table
  SELECT NEST(CONCAT(state, ',', city)) AS locations
  FROM (
    SELECT state, city FROM 
    (SELECT 'florida' AS state, 'miami' AS city),
    (SELECT 'california' AS state, 'la' AS city),
    (SELECT 'romania' AS state, 'transylvania' AS city)
    ) 
  ),
  locations,     // input columns
  "[    // output schema
    'name': 'location', 'type': 'RECORD',
     'mode': 'REPEATED',
     'fields': [
       'name': 'state', 'type': 'STRING',
       'name': 'city', 'type': 'STRING'
     ]    
    
  ]",
  "function(row, emit)    // function 
    for (var i = 0; i < row.locations.length; i++) 
      var c = [];
      x = row.locations[i].split(',');
      t = state:x[0], city:x[1]
      c.push(t);
      emit(location: c);  
    ;
  "
)  

请注意: 您应该使用Allow Large Results 设置目标表并取消选中Flatten Results

输出表的结果是(在 JSON 模式下)

[
  
    "location": [
      
        "state": "california",
        "city": "la"
      
    ]
  ,
  
    "location": [
      
        "state": "florida",
        "city": "miami"
      
    ]
  ,
  
    "location": [
      
        "state": "romania",
        "city": "transylvania"
      
    ]
  
]

添加以解决@AdiCohen 在他的真实示例中遇到的一些问题 他在最近的 cmets 中展示了:

问:我的查询除了记录列之外还有其他列,但是当我运行时 查询,它们返回为空。我怎样才能创建一个表 类型?

SELECT amount, currency, location.state, location.city FROM JS( 
  ( // input table 
    SELECT NEST(CONCAT(state, ',', city)) AS locations, 
      SUM(amount) AS amount, MAX(currency) as currency 
    FROM ( 
      SELECT state, city, amount, currency, ROW_NUMBER() OVER() as grp FROM 
        (SELECT 'florida' AS state, 'miami' AS city, 'coins' AS currency, 40 AS amount), 
        (SELECT 'california' AS state, 'la' AS city, 'coins' AS currency, 40 AS amount), 
        (SELECT 'romania' AS state, 'transylvania' AS city,'coins' AS currency, 40 AS amount) 
    ) GROUP BY grp
  ), 
  amount, currency, locations, // input columns 
  "[ // output schema 
    'name': 'location', 'type': 'RECORD', 'mode': 'REPEATED', 
    'fields': [ 
      'name': 'state', 'type': 'STRING', 
      'name': 'city', 'type': 'STRING' 
    ] , 
     'name': 'amount', 'type': 'INTEGER', 
     'name': 'currency', 'type': 'STRING' 
  ]", 
  "function(row, emit)  // function 
    for (var i = 0; i < row.locations.length; i++)  
      var c = []; 
      x = row.locations[i].split(','); 
      t = state:x[0], city:x[1] 
      c.push(t); 
      emit(amount: row.amount, currency: row.currency, location: c); 
    ; 
  "
) 

这里的输出是:

[
  
    "amount": "40",
    "currency": "coins",
    "location_state": "romania",
    "location_city": "transylvania"
  ,
  
    "amount": "40",
    "currency": "coins",
    "location_state": "florida",
    "location_city": "miami"
  ,
  
    "amount": "40",
    "currency": "coins",
    "location_state": "california",
    "location_city": "la"
  
]

【讨论】:

非常感谢!它真的有帮助。在哪里可以找到更多关于 udf 函数的内容? 嗨,你能帮帮我吗?我的查询除了记录列之外还有其他列,但是当我运行查询时,它们返回为空(此评论中没有足够的空间)。如何创建具有这两种类型的表 SELECT amount,location.state, location.city FROM JS( ( // 输入表 SELECT NEST(CONCAT(state, ',', city)) AS locations,sum(integer(amount))作为金额 FROM ( SELECT state, city FROM (SELECT 'florida' AS state, 'miami' AS city, 'coins' as currency, 40 as amount), (SELECT 'california' AS state, 'la' AS city, 'coins' ' 作为货币,40 作为金额),(选择“罗马尼亚”作为州,“特兰西瓦尼亚”作为城市,“硬币”作为货币,40 作为金额))), locations, // 输入列 "[ // 输出模式 'name': 'location', 'type': 'RECORD', 'mode': 'REPEATED', 'fields': [ 'name': 'state', 'type': 'STRING', 'name': 'city', 'type': 'STRING' ] , 'name': 'amount', 'type' : 'string' ]", "function(row, emit) // 函数 for (var i = 0; i @Adi Cohen - 我很乐意帮助你 - cmets 不适合提出新问题。我建议您 1. 接受这个答案(看起来它对您有用)和 2. 发布新问题以及您刚刚提供的所有详细信息。我很乐意回答。【参考方案2】:

您需要使用dot 表示法将输出反映为RECORD 示例查询:

select 
  'florida' as country.state, 
  'SFO' as country.city;

在此示例中,country 是记录,state|city 是记录中的字段。

【讨论】:

请澄清 - 这应该与 BQ UI 一起使用吗?或 API Explorer - cloud.google.com/bigquery/docs/reference/v2/jobs/insert#try-it ?以上建议在 BQ UI 中从来没有为我工作过!例如,您能否提供使用 API Explorer 的工作设置示例?会很有帮助的! 这个答案直接来自@MoshaPasumansky 的付费谷歌支持,他为我们几个月前发布的一张票提供了答案 它有效,但不要被标题名称所迷惑,试试这个:select country.state from ( select 'florida' as country.state, 'SFO' as country.city ) 要进一步验证,请尝试选择无效的内容,例如:country.xyq,它会响应 Field 'country.xyq ' 未找到,因此记录已正确创建。 问题是“创建一个列类型为 RECORD 的表”。所以我问 - 你真的用你的答案试过这个吗?因为,正如我所说 - 它从来没有为我醒来。只需在不创建表或输出到表的情况下运行它 - 什么也没说!同时 - 我可能会错过一些东西,这就是我问的原因 我刚试了,效果很好,单元格是新表中的一条记录:screencast.com/t/5LFSIMFJ

以上是关于创建列类型为 RECORD 的表的主要内容,如果未能解决你的问题,请参考以下文章

在BigQuery中更改记录列的类型

USQL 使用用户定义的数据类型列创建用户定义的表类型

创建具有记录类型列的表

根据 RECORD(repeated) 类型的列中不存在键来过滤 ROWs 列

如何创建具有 json 数据类型列的表

创建的表的列类型概述