MySQL:内连接结合SUM函数返回错误结果问题排查
解决SQL查询中SUM结果偏大的问题
嘿,我完全懂你遇到的麻烦!你写的SQL之所以会出现SUM数值偏大的情况,核心原因是直接连接sagecl_import和sagecl_export产生了笛卡尔积。举个简单例子:假设某个商品在采购表中有3条记录,销售表中有2条记录,当你把这两个表直接内连接时,会生成3×2=6条组合记录。这时候计算SUM的时候,采购数量会被重复统计2次,销售数量会被重复统计3次,结果当然就比实际大很多啦。
下面给你两种靠谱的解决方案:
方案一:先聚合子表,再连接主表
这种方法先分别计算每个商品的总采购量和总销售量,确保每个商品在子查询中只有一条记录,再和商品主表连接,彻底避免笛卡尔积:
SELECT a.Article, COALESCE(i.TotalImport, 0) AS IMPORT, COALESCE(e.TotalExport, 0) AS EXPORT, COALESCE(i.TotalImport, 0) - COALESCE(e.TotalExport, 0) AS Difference FROM sagecl_Article a LEFT JOIN ( -- 先统计每个商品的总采购量 SELECT Article, SUM(Quantity) AS TotalImport FROM sagecl_import GROUP BY Article ) i ON a.Article = i.Article LEFT JOIN ( -- 先统计每个商品的总销售量 SELECT Article, SUM(Quantity) AS TotalExport FROM sagecl_export GROUP BY Article ) e ON a.Article = e.Article WHERE a.Article = ?
这里用LEFT JOIN是为了兼容那些只有采购记录、没有销售记录,或者反过来的商品;COALESCE函数是把NULL值转换成0,这样差值计算不会出现异常。
方案二:使用关联子查询直接计算总和
这种方式更简洁,直接在SELECT语句中通过子查询获取单个商品的采购和销售总和,同样不会产生笛卡尔积:
SELECT a.Article, (SELECT SUM(Quantity) FROM sagecl_import WHERE Article = a.Article) AS IMPORT, (SELECT SUM(Quantity) FROM sagecl_export WHERE Article = a.Article) AS EXPORT, COALESCE((SELECT SUM(Quantity) FROM sagecl_import WHERE Article = a.Article), 0) - COALESCE((SELECT SUM(Quantity) FROM sagecl_export WHERE Article = a.Article), 0) AS Difference FROM sagecl_Article a WHERE a.Article = ?
另外提醒你一下:你原来的查询里同时选择了a.Article、b.Article、c.Article,其实这三个值是完全相等的(因为连接条件就是商品编号匹配),所以只需要保留一个就够啦。
内容的提问来源于stack exchange,提问作者Manfred Singer
相关产品推荐
相关产品推荐

