电话
400 9058 355
GROUP BY后SELECT中必须出现的字段是所有非聚合字段,且须在GROUP BY子句中明确列出;否则在ONLY_FULL_GROUP_BY模式下报错。
MySQL 8.0.13+ 默认启用 sql_mode=ONLY_FULL_GROUP_BY,这意味着:SELECT 列表里所有非聚合字段(如 name、status)都必须明确出现在 GROUP BY 子句中。否则会报错:Expression #1 of SELECT list is not in GROUP BY clause。
常见错误写法:
SELECT id, name, COUNT(*) FROM users GROUP BY status;
这里 id 和 name 既没被聚合,也没在 GROUP BY 中,MySQL 直接拒绝执行。
GROUP BY id, name, status(但通常这会失去分组意义)SELECT status, COUNT(*), AVG(age) FROM users GROUP BY status
name,用 ANY_VALUE(name) 显式声明(MySQL 5.7.5+),避免关掉 ONLY_FULL_GROUP_BYGROUP BY 本身不提供“取组内某行”的能力,它只负责聚合计算。想拿每组最新一条(比如按 create_time 最大),不能靠 MAX(create_time) 直接反查整行数据——那只是时间值,不是整条记录。
典型误操作:
SELECT user_id, MAX(create_time), content FROM logs GROUP BY user_id;
这段 SQL 在非 ONLY_FULL_GROUP_BY 模式下可能“跑通”,但 content 值是随机的(来自该组某条不确定的记录),不可靠。
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY create_time DESC),再外层筛选 rn = 1
GROUP_CONCAT 拼接后截取,逻辑脆弱且无法处理含逗号的字段值WHERE 过滤的是原始行,HAVING 过滤的是分组后的聚合结果。二者不能互换,且执行顺序固定:FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY。
例

SELECT user_id, COUNT(*) c FROM orders GROUP BY user_id HAVING c > 5
SELECT user_id, COUNT(*) c FROM orders WHERE c > 5 GROUP BY user_id —— c 是聚合结果,WHERE 阶段还不存在WHERE status = 'paid')GROUP BY 不一定慢,慢往往是因为没走索引。MySQL 对 GROUP BY 的优化依赖于 B+ 树索引的有序性——如果 GROUP BY 字段上有索引,且查询中涉及的字段(SELECT 列、WHERE 条件)能被该索引覆盖,就能避免临时表和文件排序。
EXPLAIN SELECT status, COUNT(*) FROM users GROUP BY status,重点看 type 是否为 index 或 range,Extra 是否含 Using temporary; Using filesort
GROUP BY 字段 + WHERE 字段 + SELECT 中的非聚合字段 排序创建,例如:INDEX(status, created_at, name)
GROUP BY 配合 ORDER BY 不同字段,极易触发临时表;如必须排序,优先让排序字段也进入索引分组统计真正的坑不在语法,而在对“GROUP BY 作用域”的误解——它只定义聚合维度,不定义行选取逻辑。很多看似“能跑”的 SQL,其实返回结果不可控,上线后数据对不上才暴露问题。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...