MySQL错误1111:聚合函数使用不当——按小时统计电压稳定性报错
错误原因与解决方案
错误分析
MySQL错误码1111的直接原因是聚合函数嵌套使用:你在SUM()聚合函数内部调用了另一个聚合函数AVG(),这是MySQL不允许的。
同时你的分组逻辑不符合需求:GROUP BY ip, HOUR(time)会将每个IP的每小时数据拆分为单独行,但你要的是每个IP一行,各小时的稳定性作为列展示。
另外,你的统计逻辑是计算每小时内volt不为0的记录占比(电压稳定性),需要先按IP+小时分组计算单小时的稳定性,再将结果转成列。
修正后的SQL
SELECT ip, CAST(MAX(CASE WHEN hour_num = 1 THEN stability ELSE 0 END) AS DECIMAL(2,1)) AS `1`, CAST(MAX(CASE WHEN hour_num = 2 THEN stability ELSE 0 END) AS DECIMAL(2,1)) AS `2`, CAST(MAX(CASE WHEN hour_num = 3 THEN stability ELSE 0 END) AS DECIMAL(2,1)) AS `3` FROM ( -- 先计算每个IP每小时的电压稳定性(volt非0的比例) SELECT ip, HOUR(time) AS hour_num, AVG(IF(volt = 0, 0, 1)) AS stability FROM UPS_Status WHERE time BETWEEN NOW() - INTERVAL 24 HOUR AND NOW() GROUP BY ip, HOUR(time) ) AS hourly_stats GROUP BY ip;
逻辑说明
- 子查询
hourly_stats:先按ip和HOUR(time)分组,计算每个IP每小时内volt不为0的记录占比(用AVG(IF(volt=0,0,1))实现,等价于COUNT(CASE WHEN volt<>0 THEN 1 END)/COUNT(*))。 - 外层查询:通过
CASE条件聚合,将每个IP的各小时稳定性转成列,用MAX()是因为每个IP+小时在子查询中只有一条数据,MAX()可以取出对应小时的稳定性值,其他小时为0。 - 用
CAST(...) AS DECIMAL(2,1)确保结果保留一位小数,符合你原本的格式需求。
内容的提问来源于stack exchange,提问作者haka
相关产品推荐
相关产品推荐

