必须用 GROUP BY 配合 JOIN 才能按部门汇总薪资,因为 SUM() 单独使用只返回全表总和;正确写法是关联 departments 和 employees 表后,按部门 ID 和名称分组求和。

直接用 SUM() 不加 GROUP BY,永远得不到“按部门”的结果——它只会返回一个全表总和。
为什么 SELECT SUM(amount) FROM employees 只出一行?
因为 SUM() 是聚合函数,天生把多行压成一行。它不关心“谁属于哪个部门”,只负责把所有 amount 加起来。想按部门拆开,必须告诉数据库“以什么为单位分组”。
- 错误写法:
SELECT dept_name, SUM(salary) FROM employees;→ 报错或结果不可靠(MySQL 5.7+ 严格模式下直接报错) - 正确前提:所有非聚合字段(如
dept_name)必须出现在GROUP BY中 - 本质是:先分组,再对每组单独运行
SUM()
标准写法:JOIN + GROUP BY + SUM()
部门名通常在另一张表里(比如 departments),不能只查员工表就拿到部门名称。必须关联后分组:
SELECT d.dept_name, SUM(e.salary) AS total_salary FROM departments d JOIN employees e ON d.dept_id = e.dept_id GROUP BY d.dept_id, d.dept_name;
- 用
JOIN拉出部门名称,避免在employees表里硬编码部门 ID 或名称 -
GROUP BY必须包含d.dept_id(主键)和d.dept_name(业务字段),否则可能因去重逻辑出问题 - 如果要包含“没有员工的部门”,把
JOIN换成LEFT JOIN,并注意SUM(e.salary)对空组返回NULL
遇到 NULL 或重复部门名怎么办?
SUM() 自动跳过 salary 为 NULL 的记录,但部门字段本身为 NULL 会单独分一组,导致结果里出现一行 NULL 部门。
- 过滤空部门:
WHERE e.dept_id IS NOT NULL(推荐,语义清晰) - 补默认名(慎用):
COALESCE(d.dept_name, '未知部门'),但需确认是否符合报表口径 - 查重检查:
SELECT dept_name, COUNT(*) FROM departments GROUP BY dept_name HAVING COUNT(*) > 1,避免同名不同部门污染汇总
性能容易被忽略的点
大表上跑这个查询慢?大概率卡在两个地方:
-
departments和employees的连接字段(dept_id)没索引 → 给两张表的dept_id都建 B-tree 索引 - 写了
WHERE dept_name LIKE '%技术%'却没给dept_name建索引 → 模糊前缀查询需要索引支持 - 用
GROUP BY UPPER(dept_name)这类函数 → 索引失效,改用生成列或冗余字段
真正上线前,一定要看 EXPLAIN 输出,确认是否走了索引、有没有临时表或文件排序。

















