【问题标题】:How can I avoid and/or clean duplicated row in BigQuery?如何避免和/或清除 BigQuery 中的重复行?
【发布时间】:2018-08-06 13:23:17
【问题描述】:

当我有潜在的重复行时,我应该如何每天在 BigQuery 中导入数据?

这里有一点上下文。我每天都会将数据从电子表格更新到 BigQuery。我正在使用带有简单 WRITE_APPEND 方法的 Google App Script。

有时我会导入前一天已经导入的数据。所以我想知道如何避免这种情况?

我可以构建一个 sql 查询以便每天从重复行中清除我的表吗?或者这是否可以在导入它们之前检测到重复(例如在我的作业定义中使用一些特定命令......)?

谢谢!

【问题讨论】:

  • 您是否有唯一的列,例如 ID 或插入时间戳?您也许可以找到过去有关删除重复项的答案。

标签: google-bigquery


【解决方案1】:
  • 第 1 步:准备一张要导入数据的工作表

  • 第 2 步:将您的电子表格设置为 BigQuery 中的联合数据源。

  • 第 3 步:使用 DML 将数据加载到现有表中

(需要#standardSql)

#standardSQL
INSERT INTO `fh-bigquery.tt.test_import_native` (id, data)
SELECT *
FROM `fh-bigquery.tt.test_import_sheet` 
WHERE id NOT IN (
  SELECT id 
  FROM `fh-bigquery.tt.test_import_native`
)

WHERE id NOT IN (...) 确保仅将具有新 ID 的行加载到表中。

【讨论】:

  • 请注意,如果同时运行多个 INSERT INTO 语句,使用此方法仍然可以在表中获取重复项。
【解决方案2】:

据我所知,Felipe Hoffa 提供的答案是避免重复行的最有效方法,因为 Bigquery 在加载数据时不会对数据进行规范化。原因是 Bigquery 在非规范化数据[1] 上表现最好。为了更好地理解它,我建议您查看this SO thread

我还想建议使用 SQL 聚合或分析函数来清除 Bigquery 表中的重复行,正如 Felipe Hoffa 或 Jordan Tigani 在 this SO question 中的回答。

【讨论】:

  • 感谢您的回答。 Felipe 的回答更直接,但你的回答也很有价值。
【解决方案3】:

如果您有一个大型分区表,并且只想删除给定范围内的重复项而不扫描(节省成本)并替换整个表。

使用下面的 MERGE SQL:

-- WARNING: back up the table before this operation
-- FOR large size timestamp partitioned table 
-- -------------------------------------------
-- -- To de-duplicate rows of a given range of a partition table, using surrage_key as unique id
-- -------------------------------------------

DECLARE dt_start DEFAULT TIMESTAMP("2019-09-17T00:00:00", "America/Los_Angeles") ;
DECLARE dt_end DEFAULT TIMESTAMP("2019-09-22T00:00:00", "America/Los_Angeles");

MERGE INTO `your_project`.`data_set`.`the_table` AS INTERNAL_DEST
USING (
  SELECT k.*
  FROM (
    SELECT ARRAY_AGG(original_data LIMIT 1)[OFFSET(0)] k 
    FROM `your_project`.`data_set`.`the_table` AS original_data
    WHERE stamp BETWEEN dt_start AND dt_end
    GROUP BY surrogate_key
  )

) AS INTERNAL_SOURCE
ON FALSE

WHEN NOT MATCHED BY SOURCE
  AND INTERNAL_DEST.stamp BETWEEN dt_start AND dt_end -- remove all data in partiion range
    THEN DELETE

WHEN NOT MATCHED THEN INSERT ROW

信用:https://gist.github.com/hui-zheng/f7e972bcbe9cde0c6cb6318f7270b67a

【讨论】:

    猜你喜欢
    • 2017-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多