如何查找SQL重复项的记录_结合GROUP BY与HAVING计数

老浩吖_5568

老浩吖_5568

2026-04-02

416人浏览

原创

用GROUP BY和HAVING查重复需先按目标字段分组,再用HAVING COUNT(*)>1筛选出现多次的组;若要返回所有重复行,须用子查询或窗口函数配合IN/JOIN。

如何查找sql重复项的记录_结合group by与having计数

怎么用 GROUP BY 和 HAVING 找出重复的行

直接看核心逻辑:先按想判断是否重复的字段分组,再用 HAVING COUNT(*) > 1 筛出组内有多条记录的组。这不是“查重”,而是“查哪些值组合出现了多次”。

常见错误是只写 SELECT * 后跟 GROUP BY——这在严格 SQL 模式下会报错,因为非分组字段不能直接选;更关键的是,你真正需要的往往不是“某组里随便一条”,而是“把重复的完整记录都捞出来”。

  • 想查「用户名重复」就 GROUP BY user_name
  • 想查「邮箱+手机号同时重复」就 GROUP BY email, phone
  • HAVING COUNT(*) > 1 是硬门槛,>= 2 也行,但语义不如 > 1 直观
  • MySQL 5.7+ 默认开启 sql_mode=ONLY_FULL_GROUP_BY,所以 SELECT * + GROUP BY id 这类写法会失败

查出所有重复记录(不止一行代表)

上面的 GROUP BY + HAVING 只返回每组一条聚合结果,比如用户名和出现次数。但业务中常要导出所有重复的原始数据——这时得套一层子查询或用窗口函数。

兼容性优先的做法(适用 MySQL 5.6/PostgreSQL/SQL Server):

SELECT * FROM users
WHERE (email, phone) IN (
  SELECT email, phone
  FROM users
  GROUP BY email, phone
  HAVING COUNT(*) > 1
);

注意:(email, phone) 是行构造器语法,在 MySQL 和 PostgreSQL 中有效,SQL Server 不支持,得改用 JOIN 或 EXISTS。

  • 子查询里别漏 GROUP BY 字段,否则 HAVING 无意义
  • 如果字段可能为 NULL,IN 会失效(NULL = NULL 不成立),得改用 IS NOT DISTINCT FROM(PostgreSQL)或显式判空
  • 大数据量时,给 GROUP BY 字段建联合索引能明显提速

COUNT(*) 和 COUNT(字段) 在去重场景的区别

查重复时几乎总该用 COUNT(*),而不是 COUNT(某个字段)。因为后者会自动忽略该字段为 NULL 的行,导致计数偏小,误判“不重复”。

例如用户表里 phone 允许为空,用 COUNT(phone) > 1 分组,那么所有 phone IS NULL 的记录会被当成一组且计数为 0,根本进不了 HAVING 条件。

  • COUNT(*) 统计行数,包含 NULL
  • COUNT(col) 只统计 col IS NOT NULL 的行
  • 除非你明确想排除空值再算重复(极少见),否则一律用 COUNT(*)

为什么有时候 HAVING 报错说“Unknown column”

典型错误:在 HAVING 里引用了 SELECT 列别名,比如 SELECT name AS n FROM t GROUP BY name HAVING n = 'a'。这是语法错误——HAVING 执行时机早于 SELECT 别名绑定,它看不到 n。

正确做法是重复表达式,或用子查询封装:

SELECT name FROM t GROUP BY name HAVING name = 'a';
  • 别名不能用于 WHERE、GROUP BY、HAVING,只在 ORDER BY 和 SELECT 后续中可用
  • 如果表达式复杂(比如 UPPER(TRIM(name))),建议先用子查询计算好再分组,避免重复写
  • 某些旧版 SQLite 允许别名进 HAVING,但这不是标准行为,别依赖

实际查重时最容易被绕晕的,是分不清“按什么分组”和“要返回哪些字段”。一个字段重复,不代表整行重复;而你要导出的,往往是整行数据——这时候光靠 GROUP BY + HAVING 是不够的,必须配合外层筛选。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4803

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

991

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1269

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6841

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3543

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6820

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

9461

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1290

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1132

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习