MySQL #1111分组函数误用错误排查:SQL语句问题咨询
解决MySQL #1111「分组函数误用」错误的方案
你遇到的#1111错误主要来自两个核心问题,咱们一步步拆解修复:
问题1:HAVING子句的误用与GROUP BY的不匹配
你的HAVING子句里用到了s.kickoff,但GROUP BY仅指定了s.home。在MySQL开启ONLY_FULL_GROUP_BY(默认开启)的情况下,非聚合列必须出现在GROUP BY子句中,否则会触发分组函数误用错误。
更关键的是,你用s.kickoff做时间过滤的逻辑应该放在WHERE子句里,而不是HAVING:WHERE是分组前筛选符合条件的行,HAVING是分组后筛选整个分组的结果,这里你要的是开球时间在特定范围的比赛,显然属于分组前的过滤。
问题2:聚合函数嵌套使用
你的SQL里把count(i.home)直接嵌套在SUM()内部(比如Sum(((...)/(count(i.home)))*100)),MySQL不允许在一个聚合函数里直接调用另一个聚合函数——聚合函数是对分组后的数据集计算,嵌套的话逻辑上无法正确执行。你需要先计算出每个分组的总记录数,再用这个值去计算各项比例。
修正后的SQL
下面是调整后的语句,我把计算分组记录数的逻辑提出来,同时修复了WHERE/HAVING的使用,还优化了重复的求和逻辑:
SELECT CURRENT_TIME, s.kickoff, s.home, s.away, -- 用预先计算的分组记录数count_home计算各项指标 Sum((i.FHG_total / i.count_home) * 100) AS averageFHGHome, Sum(((CASE WHEN i.FHG_total > 0.5 THEN 1 ELSE 0 END) / i.count_home) * 100) AS occurFHGHome, Sum(((CASE WHEN i.FHG_total > 1.5 THEN 1 ELSE 0 END) / i.count_home) * 100) AS occur2FHGHome, Sum((i.SHG_total / i.count_home) * 100) AS averageSHGHome, Sum(((CASE WHEN i.SHG_total > 0.5 THEN 1 ELSE 0 END) / i.count_home) * 100) AS occurSHGHome, Sum(((CASE WHEN i.SHG_total > 1.5 THEN 1 ELSE 0 END) / i.count_home) * 100) AS occur2SHGHome, Sum((i.MG_total / i.count_home) * 100) AS averageMG, Sum(((CASE WHEN i.MG_total > 0.5 THEN 1 ELSE 0 END) / i.count_home) * 100) AS occur1MG, Sum(((CASE WHEN i.MG_total > 1.5 THEN 1 ELSE 0 END) / i.count_home) * 100) AS occur2MG, Sum(((CASE WHEN i.MG_total > 2.5 THEN 1 ELSE 0 END) / i.count_home) * 100) AS occur3MG FROM saturday s INNER JOIN ( -- 子查询:提前计算分组记录数和各时间段的总数值,简化主查询 SELECT Home, (010H+010A+1020H+1020A+2030H+2030A+3040H+3040A+4045H+4045A) AS FHG_total, (4560H+6070H+7080H+80FTH+4560A+6070A+7080A+80FTA) AS SHG_total, (010H+010A+1020H+1020A+2030H+2030A+3040H+3040A+4045H+4045A+4560H+6070H+7080H+80FTH+4560A+6070A+7080A+80FTA) AS MG_total, COUNT(*) AS count_home FROM ITACornerNew GROUP BY Home ) i ON s.home = i.Home WHERE s.kickoff > SUBTIME(CURRENT_TIME, '01:45:00') AND s.kickoff < CURRENT_TIME GROUP BY s.kickoff, s.home, s.away -- 将所有非聚合列加入GROUP BY,符合ONLY_FULL_GROUP_BY规则 ORDER BY s.kickoff ASC;
额外说明
子查询里提前计算的FHG_total、SHG_total、MG_total,避免了主查询中重复写冗长的字段求和逻辑,让SQL更易读也更便于后续维护。
内容的提问来源于stack exchange,提问作者C-Sway
相关产品推荐
相关产品推荐

