如何在不更改表模式的情况下将查询结果存储在当前表中?

时间:2016-01-25 07:52:17

标签: sql-update schema google-bigquery overwrite

我有一个结构

  {
    id: "123",
    scans:[{
       "scanid":"123",
       "status":"sleep"
      }]
  },
  {
    id: "123",
    scans:[{
       "scanid":"123",
       "status":"sleep"
      }]
  }

查询删除重复:

      SELECT *
    FROM (
      SELECT
          *,
          ROW_NUMBER()
              OVER (PARTITION BY id)
              row_number,
      FROM table1
    )
    WHERE row_number = 1

我将目标表指定为table1。

这里我将扫描作为重复记录,扫描为字符串,状态为字符串。但是,当我进行一些查询(我正在进行查询以删除重复)并覆盖现有表时,表模式已更改。它变为scans_scanid(string)scans_status(string)。扫描记录模式现在已更改。请告诉我哪里出错?

2 个答案:

答案 0 :(得分:2)

众所周知,NEST()与UnFlatten Results Output不兼容,主要用于子查询中的中间结果。

尝试以下解决方法
注意,我使用INTEGER作为id和scanid。如果他们应该是STRING你需要 一个。在输出模式部分进行更改
以及
湾在t = {scanid:parseInt(x[0]), status:x[1]}

中删除parseInt()函数的使用
SELECT id, scans.scanid, scans.status 
FROM JS(
  (      // input table
    SELECT id, NEST(CONCAT(STRING(scanid), ',', STRING(status))) AS scans
    FROM (
      SELECT id, scans.scanid, scans.status 
      FROM (
        SELECT id, scans.scanid, scans.status, 
               ROW_NUMBER() OVER (PARTITION BY id) AS dup
        FROM table1
      ) WHERE dup = 1  
    ) GROUP BY id
  ),
  id, scans,     // input columns
  "[{'name': 'id', 'type': 'INTEGER'},    // output schema
    {'name': 'scans', 'type': 'RECORD',
     'mode': 'REPEATED',
     'fields': [
       {'name': 'scanid', 'type': 'INTEGER'},
       {'name': 'status', 'type': 'STRING'}
     ]    
    }
  ]",
  "function(row, emit){    // function 
    var c = [];
    for (var i = 0; i < row.scans.length; i++) {
      x = row.scans[i].toString().split(',');
      t = {scanid:parseInt(x[0]), status:x[1]}
      c.push(t);
    };
    emit({id: row.id, scans: c});  
  }"
)

我在这里使用BigQuery User-Defined Functions。它们非常强大但仍有一些LimitsLimitations需要注意。还要记住 - 他们是合格的High-Compute queries

的候选人
  

复杂查询会占用非常大的计算资源   相对于处理的字节数。通常,此类查询   包含大量的JOIN或CROSS JOIN子句或复杂   用户定义的函数。

答案 1 :(得分:1)

1)如果您在网络用户界面上运行查询,结果会自动flattened,这就是您看到架构发生变化的原因。

您需要运行查询并写入destination table,您也可以在网络用户界面上选择这样做。

2)如果您未在网络用户界面上运行查询但仍看到架构已更改,则应进行明确选择,以便为您保留架构,例如:

select 'foo' as scans.scanid

这会为您创建一个类似输出的记录,但它不会成为重复记录,请进一步阅读。

3)对于某些用例,您可能需要使用NEST(expr) function

  

将当前聚合范围中的所有值聚合为重复   领域。例如,查询&#34; SELECT x,NEST(y)FROM ... GROUP BY x&#34;   为每个不同的x值返回一个输出记录,并包含一个   在查询输入中与x配对的所有y值的重复字段。该   NEST函数需要GROUP BY子句。

     

BigQuery会自动展平查询结果,因此如果您使用NEST   在顶级查询上的功能,结果不会包含重复   领域。使用产生的子选择时使用NEST功能   中间结果,供同一查询立即使用。