【问题标题】:How to replace timestamp-partitioned table data in BigQuery?如何替换 BigQuery 中的时间戳分区表数据?
【发布时间】:2020-09-30 05:45:09
【问题描述】:

我要解决的问题是从TIMESTAMP 类型列引用的特定分区中删除重复项。我的表类似于下面的架构,时间戳列分区具有基于天的粒度:

requestID:STRING, ts:TIMESTAMP, recordNo:INTEGER, recordData:STRING

现在我有数以百万计的这些,有时会有这样的重复:

'server1234', '2020-06-10', 1, apple
'server1234', '2020-06-10', 1, apple
'server1234', '2020-06-10', 2, orange
'server1234', '2020-06-10', 2, orange

记录的唯一性由两个字段确定:requestIDrecordNo。我想删除CAST(ts AS DATE) = '2020-06-10' 所在分区中的重复项。我可以通过简单的选择看到 distinct 记录:

SELECT DISTINCT * FROM mytable WHERE CAST(ts AS DATE) = '2020-06-10'

必须有一种方法可以将删除/更新/合并与 select distinct 结合起来,以便我可以用去重数据替换分区。

想法?

【问题讨论】:

    标签: google-bigquery


    【解决方案1】:

    执行此操作的最安全方法是仅选择您需要的数据(已删除重复数据)到新表中,删除永久表中的数据,然后将已删除重复数据的数据重新插入永久位置。 BigQuery 不像某些 OLTP 数据库那样使更新/删除方法变得简单。

    如果您更喜欢一次性的方法,这里有一个示例,您提供的数据可以解决问题。

    -- SETUP
    CREATE TABLE working.remove_dupes
    (
      requestID STRING,
      ts TIMESTAMP,
      recordNo INT64,
      recordData STRING
    )
    PARTITION BY TIMESTAMP_TRUNC(ts, HOUR);
    
    INSERT INTO working.remove_dupes(requestID, ts, recordNo, recordData)
    VALUES
    ('server1234', '2020-06-10', 1, 'apple'),
    ('server1234', '2020-06-10', 1, 'apple'),
    ('server1234', '2020-06-10', 2, 'orange'),
    ('server1234', '2020-06-10', 2, 'orange');
    
    ------------------------------------------------------------------------------------
    -- SELECTING ONLY ONE OF THE ENTRIES (NO DUPLICATES)
    SELECT
      requestID,
      ts,
      recordNo,
      recordData
    FROM (
      SELECT
        requestID,
        ts,
        recordNo,
        recordData,
        ROW_NUMBER() OVER (PARTITION BY requestID, recordNo ORDER BY ts) AS instance_num
      FROM
        working.remove_dupes
    )
    WHERE
      instance_num = 1;
    
    
    ------------------------------------------------------------------------------------
    -- REPLACE THE ORIGINAL TABLE, REMOVING DUPLICATES IN THE PROCESS
    -- BACK UP YOUR TABLE FIRST!!!!! (MAKE A COPY)
    CREATE OR REPLACE TABLE working.remove_dupes
    PARTITION BY TIMESTAMP_TRUNC(ts, HOUR)
    AS
    (SELECT
      requestID,
      ts,
      recordNo,
      recordData
    FROM (
      SELECT
        requestID,
        ts,
        recordNo,
        recordData,
        ROW_NUMBER() OVER (PARTITION BY requestID, recordNo ORDER BY ts) AS instance_num
      FROM
        working.remove_dupes
    )
    WHERE
      instance_num = 1);
    

    编辑:请注意,替换表可以(根据我的经验)消除表元数据(描述)和可能的表分区。我已更新示例以包含表分区设置。

    【讨论】:

      猜你喜欢
      • 2020-05-19
      • 2019-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多