You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL技术问询:统计学生11月Offer数时WHERE与COUNT(*)的问题

问题:查询学生11月Offer数量的SQL疑问

需求与表结构

需要编写SQL查询每个学生在11月获得的Offer数量,输出列名为Job_Offers,结果按学生Id排序。

表结构如下:

-- Students表(学生信息)
Id: INT (主键)
Name: VARCHAR

-- Jobs表(Offer信息)
Id: INT(关联Students表的Id,标识该Offer属于哪个学生)
Date: DATE(Offer发放日期)
Salary: INT(薪资)

错误代码与正确代码

错误代码(输出结果不符合预期)

SELECT COUNT(Jobs.Id) AS Job_Offers 
FROM Students
LEFT JOIN Jobs ON Students.Id = Jobs.Id
WHERE MONTH(Jobs.Date) = 11
GROUP BY Students.Id
ORDER BY Students.Id

正确代码

SELECT COUNT(Jobs.Id) AS Job_Offers 
FROM Students
LEFT JOIN Jobs ON Students.Id = Jobs.Id 
               AND MONTH(Jobs.Date) = 11
GROUP BY Students.Id
ORDER BY Students.Id

疑问解答

1. 为什么不能用WHERE子句?

LEFT JOIN的核心作用是保留左表(Students)的所有记录,哪怕右表(Jobs)没有匹配的数据(此时Jobs的字段会是NULL)。

如果把MONTH(Jobs.Date) = 11放在WHERE子句里,会对LEFT JOIN后的完整结果集做过滤:

  • 对于11月没有拿到Offer的学生,Jobs.Date是NULL,MONTH(NULL)的结果也是NULL,NULL = 11不成立,这类学生的记录会被直接过滤掉,最终结果里就看不到他们的Job_Offers=0的记录,完全不符合“每个学生都要统计”的需求。

而把条件放在JOIN的ON子句里,是在表关联阶段就只筛选11月的Jobs记录,没有匹配到的学生依然会被保留,对应的Jobs字段为NULL,后续统计时就能得到正确的0值。

2. 为什么COUNT(*)无法正常工作?

COUNT(*)会统计所有非空的行,包括LEFT JOIN后生成的“学生无匹配Offer”的记录——因为这些行里Students的字段都是有效值,COUNT(*)会把这行算成1,而不是正确的0。

而COUNT(Jobs.Id)只会统计Jobs.Id不为NULL的行数:只有当学生有11月的Offer时,Jobs.Id才会有值,否则是NULL不会被统计,这样就能得到准确的Offer数量,包括无Offer时的0。

内容的提问来源于stack exchange,提问作者Abhishek Verma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 23:50:02