SQL查询计数异常问题:请求修正代码以获取正确结果
咱们先看你遇到的问题:明明Kobe和LeBron上月有完成检查,但他们还是被放进了not_complete表,而且rowcount全是0。这是因为你的查询里有几个关键错误,我帮你逐一梳理并修正:
1. 拼写错误与字符串常量未加引号
你的LEFT JOIN inspections条件里,Type_of_Inspetion少了一个字母c(正确列名是Type_of_Inspection),而且HS_Rep_Monthly是字符串类型的检查类型,必须用单引号包裹,否则数据库会把它当成一个列名,导致没有任何inspection记录能匹配上,最终所有rowcount都变成0。
2. 分组逻辑不符合SQL标准
你在GROUP BY里只指定了p.HS_Rep,但SELECT里却包含了p.ID,这在开启ONLY_FULL_GROUP_BY模式的数据库(比如MySQL默认配置)里会直接报错,而且即使不报错,返回的p.ID也是不确定的(如果同一个HS_Rep对应多个项目的话)。正确的做法是把所有非聚合列都加入GROUP BY,或者用聚合函数(比如MAX(p.ID))来获取对应的ID。
3. 日期处理的健壮性问题
用month(i.date) = month(curdate()) -1的话,当当前月份是1月时,month(curdate())-1会等于0,无法正确匹配去年12月的数据。我们可以用日期范围来精准匹配上月的所有记录,这样不管当前是哪个月都能正确工作。
修正后的完整代码
DELETE FROM `not_complete` WHERE 1 = 1; INSERT INTO `not_complete` (ID, HS_Rep, rowcount, HS_Rep_Email) SELECT p.ID, p.HS_Rep, COUNT(i.Lead_Inspector) AS rowcount, e.Email FROM projects p LEFT JOIN employee e ON p.HS_Rep = e.Lastname_Firstname LEFT JOIN inspections i ON p.HS_Rep = i.Lead_Inspector AND i.date >= DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01') AND i.date < DATE_FORMAT(CURDATE(), '%Y-%m-01') AND i.Type_of_Inspection = 'HS_Rep_Monthly' -- 修正拼写并添加单引号 WHERE p.active = "Yes" GROUP BY p.ID, p.HS_Rep, e.Email -- 包含所有非聚合列 HAVING COUNT(i.Lead_Inspector) = 0; -- 明确等于0,比<1更清晰
修正后的预期结果
执行这段代码后,not_complete表只会包含未完成上月检查的HS_Rep:
+----+-----------------+----------+-------------------+
| ID | HS_Rep | rowcount | HS_Rep_Email |
+----+-----------------+----------+-------------------+
| 3 | Jordan, Michael | 0 | michael@email.com |
+----+-----------------+----------+-------------------+
这样就准确筛选出了真正未完成检查的人员,同时rowcount也能正确反映每个HS_Rep的上月检查次数(完成检查的人员会被HAVING条件排除)。
内容的提问来源于stack exchange,提问作者torjp01

