解决SQL DATEDIFF子查询返回多行错误:计算库存日期差平均值
问题解决:ERROR 1242 (21000): Subquery returns more than 1 row
你的SQL报错核心原因是:两个子查询没有和外层的Inventory行做关联,执行时会返回所有库存记录对应的日期(多行),但DATEDIFF只能接受两个单个日期值,因此触发"子查询返回多行"的错误。
修正后的查询语句
正确的做法是两次关联Time维度表,分别获取当前库存记录对应的缺货日期和补货日期,再计算单条记录的天数差,最后按产品分组求平均值:
SELECT P.nameProduct, AVG(DATEDIFF(T_stockout.fulldate, T_resupply.fulldate)) AS Time_to_stock_out FROM Inventory AS I JOIN Product AS P ON I.idProduct = P.idProduct JOIN Time AS T_stockout ON I.idTime_stockout = T_stockout.idTime JOIN Time AS T_resupply ON I.idTime_resupply = T_resupply.idTime -- 可选:过滤掉任一日期为空的无效记录 WHERE T_stockout.fulldate IS NOT NULL AND T_resupply.fulldate IS NOT NULL GROUP BY P.nameProduct;
关键说明
- 用
JOIN替代子查询:给Time表取两个别名T_stockout和T_resupply,分别关联事实表的idTime_stockout和idTime_resupply,确保每条Inventory记录都能匹配到对应的单个日期值。 - 过滤无效数据:通过
WHERE子句排除日期为空的记录,避免DATEDIFF返回NULL,影响最终平均值的准确性。 - 分组逻辑保持不变:仍然按产品名称分组,对单条记录的天数差求平均。
如果需要保留存在空日期的产品(即使部分记录无有效日期),可以把JOIN换成LEFT JOIN,并在AVG中用IFNULL处理NULL值:
SELECT P.nameProduct, AVG(IFNULL(DATEDIFF(T_stockout.fulldate, T_resupply.fulldate), 0)) AS Time_to_stock_out FROM Inventory AS I JOIN Product AS P ON I.idProduct = P.idProduct LEFT JOIN Time AS T_stockout ON I.idTime_stockout = T_stockout.idTime LEFT JOIN Time AS T_resupply ON I.idTime_resupply = T_resupply.idTime GROUP BY P.nameProduct;
内容的提问来源于stack exchange,提问作者quentin
相关产品推荐
相关产品推荐

