订阅更新

各专业学生人数:没有学生的专业也要列出

SQL 实战 123 题 · 第 25 题 中等 约 2 分钟读完

LeetCode 580 · LEFT JOIN 计数、COUNT(列) 与 COUNT(*)、多字段排序

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

专业表 LEFT JOIN 学生表,按专业分组用 COUNT(s.student_id) 计数,没有学生的专业得到 0;排序写成 student_number DESC, dept_name。COUNT(*) 和 COUNT(列) 在 LEFT JOIN 场景下结果不同,这是这道题的考点。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

学生表记录学生所属的专业 ID,专业表记录专业名称。统计每个专业的学生人数(没有学生的专业显示 0),按人数降序,人数相同按专业名升序。

表结构

  • student:student_id(主键)、student_name、gender、dept_id
  • department:dept_id(主键)、dept_name

思路

以专业表为主表 LEFT JOIN 学生表,按专业分组计数。计数必须用 COUNT(student_id):没有学生的专业关联出一行全 NULL 的记录,COUNT(*) 会把它算成 1,COUNT(列) 会忽略 NULL 得到 0。原解法漏了「人数相同按名字排序」这个要求。

参考解法

select  dept_name ,count(student_id) student_number
from department d left join student s
on d.dept_id=s.dept_id 
group by dept_name
order by student_number desc

另一种写法:补上第二排序键,并按 dept_id 分组

SELECT d.dept_name, COUNT(s.student_id) AS student_number
FROM department d
LEFT JOIN student s ON d.dept_id = s.dept_id
GROUP BY d.dept_id, d.dept_name
ORDER BY student_number DESC, d.dept_name

易错点

  • 用 COUNT(*) 会让没有学生的专业显示 1。
  • 按 dept_name 分组时,如果两个专业重名会被合并,按 dept_id 分组更稳。
  • 别忘了第二排序键 dept_name。
刷题进度保存在当前浏览器