msyql多表查询sum()重复累加问题

前言

今天产品那边反馈了一个bug:部分订单金额(筛选场景)统计的订单总额不对。我就觉得好奇了,咋会部分就不对呢?然后我就开始场景复现了,果真复现了,我们一起来看下这个问题。

场景复现

1.搜索订单(一个订单多个商品),这样容易复现,订单号:SH20190107120514818483。
2.该订单购买了两个商品,A商品100元,B商品0元,合计是100元。
3.此时订单数:1 ;订单金额:200

1

2

定位问题

表:订单表(A):shop_order 订单商品表(B):shop_order_goods

mysql 代码:

1
SELECT COUNT(DISTINCT(o.id)) as count, ifnull(sum(o.price),0) as sumprice  FROM ims_new_shop_order o  left join ims_new_shop_order_refund r on r.id =o.refundid  left join ims_new_shop_member m on m.openid=o.openid  and m.uniacid =  o.uniacid left join ims_new_shop_member_address a on o.addressid = a.id  left join ims_new_shop_saler s on s.openid = o.verifyopenid and s.uniacid=o.uniacid left join ims_new_shop_member sm on sm.openid = s.openid and sm.uniacid=s.uniacid left join ims_new_shop_order_goods sog on sog.uniacid = o.uniacid and sog.orderid = o.id  left join ims_new_shop_goods sg on sg.uniacid = o.uniacid and sg.id = sog.goodsid   WHERE  o.uniacid = 1 and o.deleted=0 and o.isparent=0 and o.istrade=0  AND locate('SH20190107120514818483',o.ordersn)>0  AND o.create_from_wxapp = 0

问题:我们会发现A表左连接B表的时候是不排除一对多的,也就是A表一条订单对应B表多条记录,但实际上这个时候我们需要去sum的金额仅仅是A表的订单金额,关联B表有多少记录我们是不需要在乎的。这个时候相当于重复统计了A表的订单金额,其实是受到了B表的影响。

解决方案

我们应该应该怎么处理:

实际上我们只需要在A表连接B表的时候,B表单独子查询处理,因为我们需要##去重B表的重复记录##,所有需要对B表group by进行分组,这样的话就不会出现sum累计的问题了。

##A left join (SELECT id,uniacid,orderid,goodsid FROM ims_new_shop_order_goods GROUP BY goodsid) ## AS sog on C##

更改后代码:

1
SELECT COUNT(DISTINCT(o.id)) as count, ifnull(sum(o.price),0) as sumprice  FROM ims_new_shop_order o  left join ims_new_shop_order_refund r on r.id =o.refundid  left join ims_new_shop_member m on m.openid=o.openid  and m.uniacid =  o.uniacid left join ims_new_shop_member_address a on o.addressid = a.id  left join ims_new_shop_saler s on s.openid = o.verifyopenid and s.uniacid=o.uniacid left join ims_new_shop_member sm on sm.openid = s.openid and sm.uniacid=s.uniacid left join (SELECT id,uniacid,orderid,goodsid FROM ims_new_shop_order_goods GROUP BY goodsid) AS sog on sog.uniacid = o.uniacid and sog.orderid = o.id  left join ims_new_shop_goods sg on sg.uniacid = o.uniacid and sg.id = sog.goodsid   WHERE  o.uniacid = 1 and o.deleted=0 and o.isparent=0 and o.istrade=0  AND locate('SH20190107120514818483',o.ordersn)>0  AND o.create_from_wxapp = 0

3