如何在条件筛选中将NULL替换为0?SQL统计主管下属人数求助
问题1:如何在条件筛选操作中将NULL值替换为0?
咱们分两种常用场景来解决:
如果是要把查询结果里的NULL换成0:
用通用SQL函数COALESCE()就行,它会返回第一个非NULL的值;MySQL也可以用专用的IFNULL()。举个实际例子:-- 通用写法,支持MySQL、PostgreSQL、SQL Server等 SELECT COALESCE(your_target_column, 0) AS column_with_zero FROM your_table; -- MySQL专属写法 SELECT IFNULL(your_target_column, 0) AS column_with_zero FROM your_table;如果是在WHERE筛选时把NULL当作0来判断:
比如你要筛选“某列值小于5”,同时想把该列为NULL的行也包含进来(把NULL视为0),直接把COALESCE()放进WHERE条件里就行:SELECT * FROM your_table WHERE COALESCE(your_target_column, 0) < 5;这样NULL值就会被当作0参与条件判断啦。
问题2:统计所有主管的下属数量(含无下属的主管)
哈哈,你的问题我一眼就看出来啦——原SQL直接从员工表T1查询,没有下属的主管在T1里根本没有对应记录,分组后自然不会出现在结果里。要解决这个,咱们得用**左连接(LEFT JOIN)**来保留所有主管,哪怕他们没下属。
优化后的SQL代码(分两种情况):
情况1:有单独的主管名单表(比如叫SupervisorList,包含所有100位主管的姓名)
这是最稳妥的方案,因为主管名单应该是独立维护的:
SELECT sl.Supervisor, IFNULL(COUNT(t1.EmpID), 0) AS start_headcount FROM SupervisorList sl LEFT JOIN `T1` t1 ON sl.Supervisor = t1.Supervisor -- 把原WHERE的条件移到ON子句里,避免过滤掉无下属的主管 AND (t1.Last_hire_date < DATE'2018-01-01' AND (t1.term_date >= DATE'2018-01-01' OR t1.term_date IS NULL)) GROUP BY sl.Supervisor ORDER BY sl.Supervisor ASC;
情况2:没有单独的主管名单表,主管姓名都在T1的Supervisor字段里
如果T1里已经包含了所有100位主管的记录(哪怕他们没有下属),可以用子查询先提取所有主管:
SELECT supervisors.Supervisor, IFNULL(COUNT(t1.EmpID), 0) AS start_headcount FROM (SELECT DISTINCT Supervisor FROM `T1`) supervisors LEFT JOIN `T1` t1 ON supervisors.Supervisor = t1.Supervisor AND (t1.Last_hire_date < DATE'2018-01-01' AND (t1.term_date >= DATE'2018-01-01' OR t1.term_date IS NULL)) GROUP BY supervisors.Supervisor ORDER BY supervisors.Supervisor ASC;
关键改动说明:
- 从主管列表出发左连接员工表:不管有没有下属,所有主管都会保留在结果里;
- 把原WHERE条件移到ON子句:如果放在WHERE里,会过滤掉左连接后T1字段为NULL的行(也就是无下属的主管),移到ON子句只会影响连接时的匹配,不会丢主表的记录;
- COUNT(t1.EmpID):左连接后无下属的主管对应的
EmpID是NULL,COUNT会自动忽略NULL值,结果就是0,加上IFNULL是双重保险(其实这里COUNT返回的已经是0,不过加上更稳妥)。
内容的提问来源于stack exchange,提问作者Sandy
相关产品推荐
相关产品推荐

