You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GROUP BY与HAVING联用SQL报错:非聚合列未在GROUP BY子句中

解决GROUP BY + HAVING 配合only_full_group_by的报错问题

嘿,我帮你分析下这个报错的原因,再给几个靠谱的解决办法!

为什么会报错?

你遇到的这个错误,核心是MySQL的only_full_group_by模式在起作用——这是MySQL默认开启的严格模式,要求SELECT列表里的所有非聚合列必须出现在GROUP BY子句里,或者这些列在功能上依赖于GROUP BY的列(比如GROUP BY的是主键,那其他列自然依赖它)。

你的子查询SELECT id FROM users GROUP BY firstname HAVING count(*) > 1里,按firstname分组,但要查询的id是非聚合列,而且同一个firstname对应多个不同的id(不然你也不会查重复项了),这就违反了only_full_group_by的规则,所以直接报错。

靠谱的解决方法

方法1:调整子查询的逻辑(最直接)

你的需求是找出所有拥有重复firstname的用户,那完全可以让子查询只返回重复的firstname值,再用这个去筛选原表:

SELECT * FROM users 
WHERE firstname IN (
    SELECT firstname FROM users 
    GROUP BY firstname 
    HAVING COUNT(*) > 1
)

这个写法完全符合only_full_group_by的要求,子查询里SELECT和GROUP BY的都是firstname,逻辑也和你的需求匹配——找出所有属于重复名字组的用户。

方法2:用窗口函数(更灵活)

如果你需要更复杂的筛选(比如只取每个重复组里的前N条记录),窗口函数是更好的选择,它不需要GROUP BY,也不会触发严格模式的限制:

SELECT * FROM (
    SELECT *,
           -- 按firstname分组,计算每个组的总记录数
           COUNT(*) OVER(PARTITION BY firstname) AS name_duplicate_count
    FROM users
) AS user_with_duplicate_count
WHERE name_duplicate_count > 1

这个查询会给每条记录加上它所属firstname组的总数量,然后筛选出数量大于1的记录,逻辑清晰还能扩展。

方法3:临时关闭only_full_group_by(不推荐)

如果只是临时测试,不想改SQL,可以临时关闭这个严格模式,但不建议长期这么做(会导致SQL结果不符合预期,违反ANSI标准):

-- 临时关闭当前会话的only_full_group_by
SET sql_mode = REPLACE(sql_mode, 'ONLY_FULL_GROUP_BY', '');

执行完这条命令后,你的原SQL就能运行了,但重启MySQL后会恢复原来的设置。

总结

优先推荐方法1或方法2,这两种写法既符合SQL规范,又能准确实现你的需求,避免后续出现其他问题。

内容的提问来源于stack exchange,提问作者Md Hasibur Rahaman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:02:13