新手提问:如何高效移除Google BigQuery表中数据及指定列的重复项?
针对你在Google BigQuery里的两个去重需求,整理了高效的实现方法:
一、移除大数据集中的全表重复数据
整行完全重复的场景,用窗口函数标记重复项再筛选唯一行是最高效的方案,适配大数据量:
CREATE OR REPLACE TABLE `project.dataset.target_table` AS SELECT * EXCEPT(rn) FROM ( SELECT *, ROW_NUMBER() OVER(PARTITION BY * ORDER BY _PARTITIONTIME DESC) AS rn FROM `project.dataset.source_table` ) WHERE rn = 1;
- 逻辑说明:
PARTITION BY *将所有列完全一致的行归为一组,ROW_NUMBER()给每组行编号;如果是分区表,ORDER BY _PARTITIONTIME DESC确保保留最新分区的行,非分区表可以指定时间戳列(没有的话用RAND()也能凑,但优先用有业务意义的列)。 - 性能优化:原表是分区/聚类表时,一定要把分区键加入
PARTITION BY的范围,减少扫描的数据量;超大规模表可以分批次处理。
如果表的列数很少,也可以直接用SELECT DISTINCT *,但列多的时候写起来麻烦,且窗口函数的可控性更强。
二、删除指定列的重复项
比如要基于user_id、order_no两列去重,保留其他列的最新数据,只需调整窗口函数的分组列:
CREATE OR REPLACE TABLE `project.dataset.target_table` AS SELECT * EXCEPT(rn) FROM ( SELECT *, ROW_NUMBER() OVER( PARTITION BY user_id, order_no ORDER BY update_timestamp DESC -- 按更新时间降序,保留最新行 ) AS rn FROM `project.dataset.source_table` ) WHERE rn = 1;
- 关键要点:
PARTITION BY后跟上你要去重的指定列,ORDER BY用来决定保留哪一行(比如最新、最早,或某列数值最大/最小的行)。 - 增量去重方案:如果需要持续清理新增数据,用MERGE语句只处理新数据,避免全表扫描:
MERGE `project.dataset.target_table` AS t USING ( SELECT * EXCEPT(rn) FROM ( SELECT *, ROW_NUMBER() OVER(PARTITION BY user_id, order_no ORDER BY update_timestamp DESC) AS rn FROM `project.dataset.new_data_table` ) WHERE rn = 1 ) AS s ON t.user_id = s.user_id AND t.order_no = s.order_no WHEN NOT MATCHED THEN INSERT ROW;
内容的提问来源于stack exchange,提问作者Jamal Khan
相关产品推荐
相关产品推荐

