MySQL使用GROUP BY与HAVING查询name字段仅出现一次的唯一记录
问题原因
- 你的原语句不符合SQL GROUP BY语法规范:GROUP BY分组后SELECT只能返回分组字段、聚合函数,直接返回source、id这类非分组非聚合字段,执行结果不可控,自然拿不到正确记录。
- 你的需求是获取「name全局唯一对应的完整行记录」,不是分组后的聚合统计结果,直接GROUP BY无法直接返回完整行数据。
解决方法
通用写法(兼容所有SQL数据库)
通过子查询先筛选出所有仅出现一次的name,再关联查询对应完整记录:
SELECT id, name, source FROM data WHERE name IN ( SELECT name FROM data GROUP BY name HAVING COUNT(*) = 1 );
执行后即可得到你预期的仅包含eee的结果。
窗口函数写法(适配MySQL8.0+、PostgreSQL、SQL Server等支持窗口函数的数据库)
用窗口函数按name分组统计出现次数,再过滤结果:
SELECT id, name, source FROM ( SELECT *, COUNT(*) OVER(PARTITION BY name) AS name_cnt FROM data ) temp WHERE name_cnt = 1;
source字段筛选说明
你直接加WHERE source = "source2"没效果,是因为没有明确筛选逻辑的作用范围,分两种常见场景:
场景1:先找全局唯一的name,再筛选这些记录中属于source2的
在主查询的WHERE条件中加source筛选即可:
SELECT id, name, source FROM data WHERE name IN ( SELECT name FROM data GROUP BY name HAVING COUNT(*) = 1 ) AND source = 'source2';
场景2:仅统计source2范围内,name仅出现一次的记录(忽略name在其他source的出现情况)
需要把source筛选同时加在子查询和主查询中:
SELECT id, name, source FROM data WHERE name IN ( SELECT name FROM data WHERE source = 'source2' GROUP BY name HAVING COUNT(*) = 1 ) AND source = 'source2';
内容的提问来源于stack exchange,提问作者Fuxi
相关产品推荐
相关产品推荐

