MySQL SUM列子查询返回多行问题:统计成员各任务协助工时
解决MySQL子查询返回多行的报错问题(ERROR 1242)
嘿,这个报错的原因很明确——你写的子查询会返回多行结果,但主查询的SELECT列表里只能接受返回单个值的子查询,所以数据库就抛出ERROR 1242 (21000): Subquery returns more than 1 row啦。咱们来一步步解决这个问题:
错误原因拆解
你的子查询:
(SELECT SUM(s.stunden) AS Zeit FROM stunden s GROUP BY s.user_id, s.einsatz_id)
会输出每个成员-任务组合的总工时,比如你的测试数据里会返回:
- 3.5(user_id=1 + einsatz_id=2)
- 2.0(user_id=1 + einsatz_id=1)
- 1.0(user_id=2 + einsatz_id=2)
- ...(其他组合)
但主查询把这个子查询当成一个单独的列值来调用,数据库无法把多行结果对应到主查询的每一行,所以冲突报错。
正确解决方案(推荐写法)
直接在主查询中完成分组求和,同时用清晰的JOIN语法关联表:
SELECT SUM(s.stunden) AS STUNDEN, m.nachname, m.vorname, a.einsatz FROM stunden s INNER JOIN mitglieder m ON s.user_id = m.id INNER JOIN arbeitseinsatz a ON s.einsatz_id = a.einsatz_id GROUP BY s.user_id, s.einsatz_id, m.nachname, m.vorname, a.einsatz ORDER BY m.nachname, m.vorname ASC;
写法说明:
- 聚合求和:直接用
SUM(s.stunden),因为已经按user_id和einsatz_id分组,自动计算每组的总工时。 - 表关联:用
INNER JOIN替代旧的逗号分隔表的写法,关联逻辑更直观,避免潜在的笛卡尔积问题。 - GROUP BY规范:包含所有非聚合列(
m.nachname, m.vorname, a.einsatz),符合MySQLONLY_FULL_GROUP_BY模式的要求,避免语法警告。
备选方案(关联子查询写法)
如果一定要用子查询,需要改成关联子查询,让子查询和主查询的user_id、einsatz_id绑定,确保每次只返回单个值:
SELECT (SELECT SUM(sub.stunden) FROM stunden sub WHERE sub.user_id = s.user_id AND sub.einsatz_id = s.einsatz_id) AS STUNDEN, m.nachname, m.vorname, a.einsatz FROM stunden s INNER JOIN mitglieder m ON s.user_id = m.id INNER JOIN arbeitseinsatz a ON s.einsatz_id = a.einsatz_id GROUP BY s.user_id, s.einsatz_id, m.nachname, m.vorname, a.einsatz ORDER BY m.nachname, m.vorname ASC;
写法说明:
子查询通过sub.user_id = s.user_id AND sub.einsatz_id = s.einsatz_id和主查询的当前行关联,只会计算当前成员-任务组合的总工时,因此返回单个值,不会触发报错。
测试结果验证
针对你的测试数据,user_id=1参与einsatz_id=2的两次工时(1.0+2.5)会被正确求和为3.5,其他组合的总工时也会准确计算。
内容的提问来源于stack exchange,提问作者BjornZ
相关产品推荐
相关产品推荐

