MySQL中无需罗列所有列,如何查询完全重复的行?
解决MySQL全列重复行查询(无需罗列所有列)
嘿,当然可以!不用手动敲几十列的列名也能轻松找出所有完全重复的行,我给你几个实用的方案,适配不同数据量的场景:
方案1:GROUP BY + JOIN(中小数据量首选)
如果你的表有主键或唯一标识列,这个方法简单直接,不用碰任何列名:
SELECT t.* FROM your_table t INNER JOIN ( -- 分组所有列,筛选出重复次数>1的分组 SELECT * FROM your_table GROUP BY * HAVING COUNT(*) > 1 ) duplicates USING (your_primary_key); -- 替换成你的主键列,比如id
原理是通过GROUP BY *让MySQL自动按所有列分组,找出重复的分组后,再关联原表获取完整的重复行。
方案2:哈希校验法(大数据量更高效)
当数据量很大时,计算每行的哈希值来判断重复会更高效,而且同样不用罗列列名。这里推荐用TO_JSON把整行转成JSON字符串(能正确处理NULL和不同数据类型),再哈希:
第一步:查看重复的哈希值及次数
SELECT MD5(REPLACE(TO_JSON(t), ' ', '')) AS row_hash, COUNT(*) AS duplicate_count FROM your_table t GROUP BY row_hash HAVING duplicate_count > 1;
第二步:获取所有重复的完整行
SELECT t.* FROM your_table t WHERE MD5(REPLACE(TO_JSON(t), ' ', '')) IN ( SELECT MD5(REPLACE(TO_JSON(t), ' ', '')) AS row_hash FROM your_table t GROUP BY row_hash HAVING COUNT(*) > 1 ) ORDER BY MD5(REPLACE(TO_JSON(t), ' ', '')); -- 按哈希值排序,方便查看重复组
优化技巧(超大数据量)
如果表的数据量特别大,可以先把哈希值存入临时表并加索引,大幅提升查询速度:
-- 创建临时表存储每行的主键和哈希值 CREATE TEMPORARY TABLE temp_row_hashes AS SELECT your_primary_key, MD5(REPLACE(TO_JSON(t), ' ', '')) AS row_hash FROM your_table t; -- 给哈希值加索引 CREATE INDEX idx_row_hash ON temp_row_hashes(row_hash); -- 关联查询获取重复行 SELECT t.* FROM your_table t JOIN temp_row_hashes trh ON t.your_primary_key = trh.your_primary_key JOIN ( SELECT row_hash FROM temp_row_hashes GROUP BY row_hash HAVING COUNT(*) > 1 ) dup ON trh.row_hash = dup.row_hash;
注意事项
- 如果你不想用
TO_JSON,也可以用CONCAT_WS('|', *)拼接所有列,但一定要选一个不会出现在任何列数据里的分隔符(比如|),避免不同列的内容拼接后产生歧义导致哈希冲突; - 对于含NULL值的列,
TO_JSON会正确保留NULL标识,比CONCAT_WS更可靠(CONCAT_WS会自动忽略NULL); - 如果你没有主键列,可以直接用哈希查询的结果,或者在临时表中用
ROW_NUMBER()生成临时标识。
内容的提问来源于stack exchange,提问作者Skintest
相关产品推荐
相关产品推荐

