一聚教程网:一个值得你收藏的教程网站

热门教程

如何借助SQL聚合函数快速查找表中的重复记录

时间:2026-06-24 08:54:52 编辑:袖梨 来源:一聚教程网

必须用GROUP BY+HAVING COUNT()>1筛选重复字段组合,因WHERE在分组前执行无法访问聚合结果;单列重复写GROUP BY email HAVING COUNT()>1,多列组合则GROUP BY user_id,order_date HAVING COUNT()>1;要获取所有重复原始行,需用窗口函数COUNT() OVER(PARTITION BY)或子查询JOIN。

用 GROUP BY + HAVING 找出重复的字段组合

直接看最常用也最可靠的方案:GROUP BY 配合 HAVING COUNT(*) > 1。它不依赖主键或唯一索引,只关心“哪些值出现了多次”。比如查 users 表里重复的 email

SELECT email, COUNT(*) AS cntFROM usersGROUP BY emailHAVING COUNT(*) > 1;

注意:必须用 HAVING 而不是 WHERE,因为 COUNT(*) 是聚合结果,WHERE 在分组前过滤,HAVING 在分组后筛选。

  • 如果要查多个字段重复(如 first_namelast_name 同时相同),就把它们全写进 GROUP BY
  • COUNT(*)COUNT(column) 更安全——后者会忽略 NULL 值,可能漏掉含空值的重复组
  • MySQL 8.0+ 或 PostgreSQL 可加 ORDER BY cnt DESC 快速定位高频重复项

用窗口函数标记每条记录是否重复(需要保留原始行)

当不只是要统计,而是想看到所有重复的完整记录(比如导出、去重或人工核对),ROW_NUMBER() 窗口函数更合适。以 PostgreSQL 或 SQL Server 为例:

SELECT *, ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) AS rnFROM usersWHERE email IN (  SELECT email FROM users GROUP BY email HAVING COUNT(*) > 1);

这样每组重复记录会被编号,rn > 1 的就是“多余副本”。关键点:

  • PARTITION BY 决定按什么分组,“重复”的定义就在这里定义
  • ORDER BY id 确保编号稳定——没 ORDER BY 会导致每次执行结果顺序不同
  • SQLite 不支持窗口函数,得用自连接或子查询模拟,性能差很多

避免 COUNT(*) 导致的性能陷阱

大表上直接跑 GROUP BY + COUNT(*) 可能慢到超时,尤其没索引时。实际优化思路:

  • 先确认重复字段是否有索引:对 emailINDEX 能让 GROUP BY 快几倍
  • EXISTS 替代全量聚合(适合只判断“是否存在重复”,不需计数):
SELECT DISTINCT emailFROM users u1WHERE EXISTS (  SELECT 1 FROM users u2   WHERE u2.email = u1.email AND u2.id != u1.id);

这个写法在有索引时通常比 GROUP BY 更快,但无法知道重复次数。

  • 千万级表慎用 COUNT(*),可先 LIMIT 100 测速,再决定是否加 WHERE 缩小范围

区分 NULL 是否算重复值

SQL 标准里,NULL = NULL 为 false,所以 GROUP BY 默认把所有 NULL 归为一组——这意味着多个 NULL 会被当成重复。这未必是你想要的:

  • 如果业务上 NULL 表示“未知”,不应视为重复,得提前过滤:WHERE email IS NOT NULL
  • 如果确实要识别 NULL 重复,保留原逻辑即可,但需在报告里注明
  • 某些数据库(如 MySQL 5.7 严格模式)可能对 GROUP BY 中非聚合字段报错,记得检查 sql_mode 或改用 ANY_VALUE()

重复检测看似简单,但字段是否允许 NULL、要不要保留原始行、表大小、索引状态——这几个点没对齐,查出来的结果可能完全不对。

灵契少女相关攻略
《灵契少女》阴间宝箱获取攻略 《灵契少女》第一章生命之树探索攻略 《灵契少女》拉卡镇全宝箱收集攻略
《灵契少女》静寂林地全宝箱收集攻略 揭秘《灵契少女》中的冰魄秘剑 《灵契少女》幽光果分布位置一览
《灵契少女》肿胀之心技能效果分享 sql中%的含义 快速掌握sql中%的作用 mysql中%的用法 mysql通配符%使用场景
如何在PostgreSQL中使用OFFSET实现SQL分页查询功能? 如何在MySQL中利用UNION运算符合并两个SQL查询结果? 为什么MySQL在执行UNION操作时性能远低于UNION ALL?
如何在SQL中实现类似于Excel的分类汇总功能? 如何解决MySQL中GROUP BY查询结果与预期不符的问题? 如何在SQL中实现对非数值类型字段的自定义规则聚合?
MySQL中UNION与UNION ALL区别 如何在SQL中利用GROUP BY和HAVING子句过滤聚合后的数据?

热门栏目