【问题标题】:How do I update a bigquery table with an array?如何使用数组更新 bigquery 表?
【发布时间】:2020-03-19 19:55:57
【问题描述】:

我有一个包含日志数据的表,我想用后续查询的结果更新它,该查询将针对过滤后的行插入结果。

我想使用 union all 来保留当前值并附加新值,但出现以下错误:

不支持引用其他表的相关子查询,除非它们可以去相关,例如通过将它们转换为有效的 JOIN。

UPDATE LOGGING.table_logs a
SET a.pinged = ARRAY(
      (SELECT AS STRUCT 
      CURRENT_TIMESTAMP() as date,b.size_bytes,timestamp_millis(b.last_modified_time) AS last_modified_time,b.row_count
      FROM  `<DATASETNAME>.__TABLES__` b WHERE table_id = CONCAT("ga_sessions_intraday_",FORMAT_DATE("%Y%m%d", CURRENT_DATE())))

      )

WHERE table_id = CONCAT("ga_sessions_intraday_",FORMAT_DATE("%Y%m%d", CURRENT_DATE()))

【问题讨论】:

    标签: google-bigquery


    【解决方案1】:

    下面根本没有经过测试,只是基于 [希望] 正确改组你的语法 - 所以它避免了“引用其他表的相关子查询”的问题

    UPDATE LOGGING.table_logs a
    SET a.pinged = ARRAY(
      SELECT AS STRUCT 
        CURRENT_TIMESTAMP() AS DATE,
        b.size_bytes,
        TIMESTAMP_MILLIS(b.last_modified_time) AS last_modified_time,
        b.row_count
    )
    FROM  `<DATASETNAME>.__TABLES__` b 
    WHERE a.table_id = b.table_id
    AND a.table_id = CONCAT("ga_sessions_intraday_",FORMAT_DATE("%Y%m%d", CURRENT_DATE())) 
    

    请检查并告诉我它现在是否有效或仍需要一些调整

    附:显然,以上假设其余逻辑是正确的

    更新:如何保留 a.pinged 中已有的内容并使用当前存在的内容以及查询结果对其进行更新?

    下面试试

    UPDATE LOGGING.table_logs a
    SET a.pinged = ARRAY_CONCAT(a.pinged, ARRAY(
      SELECT AS STRUCT 
        CURRENT_TIMESTAMP() AS DATE,
        b.size_bytes,
        TIMESTAMP_MILLIS(b.last_modified_time) AS last_modified_time,
        b.row_count
    ))
    FROM  `<DATASETNAME>.__TABLES__` b 
    WHERE a.table_id = b.table_id
    AND a.table_id = CONCAT("ga_sessions_intraday_",FORMAT_DATE("%Y%m%d", CURRENT_DATE()))
    

    【讨论】:

    • 嗨 Mikhail,我如何保留 a.pinged 中已有的内容并使用当前存在的内容以及查询结果对其进行更新?
    • 是的,它确实有效。你是BQ大师!我会分解你的代码并真正理解你做了什么不同的事情。真的很感谢你花时间看这个。我不知道你怎么变得这么好。
    • 同时,请检查我的答案中的更新 - 希望这是您所需要的
    【解决方案2】:

    我觉得您可能过度简化了您的查询,这对我来说看起来并不相关子查询,但如果您不这样做,我的感觉是您的子查询总是生成相同的数组,无论 LOGGING.table_logs 有哪一行。您可以先将数组保存在脚本变量中,然后再设置:

    DECLARE field_value DEFAULT 
    ARRAY(
          (SELECT AS STRUCT 
          CURRENT_TIMESTAMP() as date,b.size_bytes,timestamp_millis(b.last_modified_time) AS last_modified_time,b.row_count
          FROM  `<DATASETNAME>.__TABLES__` b WHERE table_id = CONCAT("ga_sessions_intraday_",FORMAT_DATE("%Y%m%d", CURRENT_DATE()))));
    
    UPDATE LOGGING.table_logs a
    SET a.pinged = field_value
    WHERE table_id = CONCAT("ga_sessions_intraday_",FORMAT_DATE("%Y%m%d", CURRENT_DATE()))
    

    【讨论】:

    • 感谢Yun,我尝试修改上面的代码以保留现有数据并附加新数据,但无法正常工作。 Mikhail 设法让它按预期工作,但感谢您的帮助。
    猜你喜欢
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多