1. 从报错出发:理解MySQL GROUP BY的核心机制
今天在开发过程中遇到一个典型的MySQL报错,让我对GROUP BY的理解有了新的认识。错误信息如下:
code复制[42000][1055] Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'deE.dname' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
这个报错的核心在于:当SQL_MODE设置为ONLY_FULL_GROUP_BY时(MySQL 5.7+默认启用),SELECT列表中的非聚合列必须出现在GROUP BY子句中,或者这些列必须功能依赖于GROUP BY的列。
1.1 功能依赖性的本质
功能依赖(functional dependency)是理解这个问题的关键。在数据库理论中,如果列X的值能唯一确定列Y的值,那么Y功能依赖于X。例如在dept表中,deptno是主键,自然能唯一确定dname和loc,因此dname和loc功能依赖于deptno。
MySQL的查询优化器会利用这种依赖关系。当看到GROUP BY deptno时,即使SELECT列表包含dname和loc,也能确定这些值在每组内是唯一的,因此不会报错。
1.2 主键的特殊地位
在标准SQL中,主键具有特殊意义。当GROUP BY后面跟的是主键列时,由于主键的唯一性,与该主键在同一表中的其他列都功能依赖于它。这就是为什么以下两个查询都能执行:
sql复制# 查询A:GROUP BY 部门表主键
select dept.deptno,dept.dname,dept.loc ,count(*)
from dept,emp
where dept.deptno=emp.deptno
group by dept.deptno;
# 查询B:GROUP BY 员工表主键
select dept.deptno,dept.dname,dept.loc ,count(
