咨询:如何删除无主键Delta表中的完全重复行
无主键Delta表整行去重实现方法
方法一:创建新的去重Delta表(最稳妥)
这种方式不修改原表,直接生成去重后的新表,适合需要保留原始数据的场景。
- 实现逻辑:通过窗口函数
row_number(),将所有字段作为分组依据,给每组重复数据编号,只保留每组中编号为1的行。 - 代码示例:
-- 替换成你的原表名和目标表名 CREATE OR REPLACE TABLE target_deduplicated_table USING delta AS SELECT * FROM ( SELECT *, -- 按所有字段分组,不指定排序则保留任意一行重复数据 ROW_NUMBER() OVER (PARTITION BY * ORDER BY (SELECT NULL)) AS row_rank FROM source_original_table ) ranked_data WHERE row_rank = 1;
如果需要保留每组重复数据中最新的一行(比如有时间字段create_time),可以修改排序规则:
ROW_NUMBER() OVER (PARTITION BY * ORDER BY create_time DESC) AS row_rank
方法二:原地删除重复行(直接修改原表)
如果不需要保留原表数据,希望直接在原表上去重,可以用以下方式:
- 实现逻辑:先通过哈希函数生成每行的唯一标识,筛选出需要保留的行的哈希值,再删除不在保留列表中的重复行。
- 代码示例:
WITH all_ranked_rows AS ( SELECT *, SHA2(CONCAT_WS('|', *), 256) AS row_hash, ROW_NUMBER() OVER (PARTITION BY * ORDER BY (SELECT NULL)) AS row_rank FROM source_original_table ), keep_rows AS ( SELECT row_hash FROM all_ranked_rows WHERE row_rank = 1 ) DELETE FROM source_original_table WHERE SHA2(CONCAT_WS('|', *), 256) IN ( SELECT row_hash FROM all_ranked_rows WHERE row_rank > 1 );
说明:CONCAT_WS('|', *)将所有字段用分隔符拼接,避免字段值为空时哈希冲突;SHA2(...,256)生成每行的唯一哈希值,用来标识重复行。
注意事项
- 如果表数据量较大,建议先对表做分区处理,再执行去重操作,提升性能。
- 若要保留重复数据中的特定行(比如最新/最早),务必调整
ORDER BY后的字段,确保结果符合预期。 - 原地删除操作前建议备份原表,避免数据丢失。
内容的提问来源于stack exchange,提问作者Harshith K R
相关产品推荐
相关产品推荐

