group by 配合 count() 是统计各部门员工人数的最直接解法,需按部门字段分组并计数,注意处理 null 值、跨表关联、排序及 limit 限制等细节。

GROUP BY 配合 COUNT() 是最直接解法
统计每个部门的员工人数,核心就是按部门分组再计数。前提是员工表里有部门字段(比如 dept_id 或 department_name),且该字段非空或你已明确空值如何处理。
- 必须用
GROUP BY指定分组依据,否则COUNT()会返回整张表的总人数 -
COUNT(*)统计每组行数,包括部门字段为NULL的记录;如果只想算有效部门,改用COUNT(dept_id)(它自动忽略NULL) - 若部门名存在重复别名(比如“研发部”和“研发中心”),先得清洗或关联部门字典表,否则会算作两个部门
遇到部门字段在另一张表里怎么办?
常见场景是员工表只有 dept_id,部门名称存在独立的 departments 表。这时必须先 JOIN,再分组。
- 用
LEFT JOIN可保留没有匹配部门的员工(department_name为NULL),适合排查脏数据 - 用
INNER JOIN则只统计部门信息完整的员工,结果更“干净”但可能漏数据 - 注意
GROUP BY必须包含所有非聚合字段,比如选了d.name,就得写GROUP BY d.name,不能只写GROUP BY e.dept_id
SELECT d.name AS department, COUNT(*) AS employee_count FROM employees e LEFT JOIN departments d ON e.dept_id = d.id GROUP BY d.name;
为什么 COUNT(1) 和 COUNT(*) 结果一样?
很多人以为 COUNT(1) 更快,其实现代数据库(MySQL 8.0+、PostgreSQL、SQL Server)对两者执行计划完全一致,都是走行计数,不读字段内容。
-
COUNT(*)是 SQL 标准写法,语义清晰——“统计行数”,推荐优先使用 -
COUNT(column)才真正依赖列:它跳过该列值为NULL的行,和COUNT(*)行为不同 - 在有大量
NULL值的列上用COUNT(col),结果会比COUNT(*)小,这点容易被忽略
统计结果要按人数倒序排列并限制前3名
加 ORDER BY 和 LIMIT(或 TOP)就能实现,但顺序不能错:必须先 GROUP BY,再 ORDER BY,最后 LIMIT。
- MySQL/PostgreSQL 用
LIMIT 3;SQL Server 用TOP 3放在SELECT后面 -
ORDER BY COUNT(*) DESC是合法写法,不必把聚合函数写进SELECT列表里重复 - 如果多个部门人数相同且并列第3,
LIMIT会随机截断,需要精确取“前N名”得用窗口函数(如DENSE_RANK())
SELECT dept_id, COUNT(*) AS cnt FROM employees GROUP BY dept_id ORDER BY cnt DESC LIMIT 3;部门字段是否为空、是否跨表、聚合后排序需求——这些细节一动,SQL 就得跟着调。别只抄模板,先看数据实际长什么样。











