【问题标题】:Delete Oldest Duplicate Rows from a BigQuery Table从 BigQuery 表中删除最旧的重复行
【发布时间】:2019-09-13 20:00:03
【问题描述】:

我有一个包含 >70M 行数据和 2M 重复数据的表。我想通过保留最近的原始行来清除重复项。

我从这里找到了一些解决方案 - link

其中,解决方案只是清除重复项,不保留重复项之间的最新数据。

这是另一个常见的解决方案:

;WITH cte 
     AS (SELECT Row_number() OVER (partition BY id ORDER BY 
                updatedAt 
                DESC, 
                status DESC) RN 
         FROM   MainTable) 
DELETE FROM cte 
WHERE  RN > 1 

但 BigQuery 不支持它。

【问题讨论】:

    标签: google-bigquery


    【解决方案1】:

    这是一种解决方法,它将现有表替换为唯一行和最近的原始行。

    CREATE OR REPLACE TABLE
      `MainTable` AS
    SELECT
      id,
      acctId,
      appId,
      createdAt,
      startTime,
      subAcctId,
      type,
      updatedAt,
      userId
    FROM (
      SELECT
        *,
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY updatedAt DESC -- the first row among duplicates will be kept, other rows will be removed
          ) RN
      FROM
        `MainTable`)
    WHERE
      RN = 1
    

    由于我们没有删除特定列 (rn) 的选项,因此必须在替换现有表时选择所需的列。

    希望这对某人有所帮助。如果您有更好的解决方案,请分享。

    【讨论】:

    • 您可以使用SELECT * EXCEPT(RN),这样您就不需要列出所有列
    • @MikhailBerlyant 我认为 EXCEPT 子句不会按照this 那样直接起作用。即使我们使用 which 也会导致另一个嵌套查询。
    • 我真的怀疑你做得对!你遇到了什么错误?
    • 哎呀,对不起。非常感谢
    • 在我的回答中查看正确的语法 :o) 如果这对您有帮助 - 考虑投票
    【解决方案2】:

    以下是 BigQuery 标准 SQL

    CREATE OR REPLACE TABLE
      `MainTable` AS
    SELECT * EXCEPT(RN)
    FROM (
      SELECT
        *,
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY updatedAt DESC -- the first row among duplicates will be kept, other rows will be removed
          ) RN
      FROM
        `MainTable`)
    WHERE
      RN = 1
    

    【讨论】:

      猜你喜欢
      • 2016-08-09
      • 2021-01-20
      • 2011-04-09
      • 2011-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-30
      • 2012-10-21
      相关资源
      最近更新 更多