MySQL多表JOIN后如何正确统计shipping_price的总和
多表关联统计订单运费总和的正确方案
你遇到的问题本质是一对多关联查询后主表字段被重复计数:订单表(主表)和订单项表(子表)是1:N关系,JOIN后每个订单会生成和订单项数量一致的重复行,直接sum主表的shipping_price会重复累加,sum(DISTINCT)又会把不同订单的相同运费值错误去重。
方案1:无订单项过滤需求时直接移除不必要的JOIN
你当前给出的SQL中WHERE条件没有用到product_item表的字段,不需要关联订单项表即可完成统计,直接删除对应JOIN逻辑即可:
SELECT sum(shipping_price) FROM `product_order` INNER JOIN `product_address` ON `product_order`.`address_id` = `product_address`.`id` WHERE (`status`<>2) AND (`company_id`=1968) AND DATE(date)='2021-08-31'
这个方案执行效率最高,没有多余的关联和去重逻辑。
方案2:需要关联订单项做过滤时,先去重主表记录再求和
如果后续需要加订单项相关的过滤条件(比如筛选购买了指定商品的订单运费),可以先通过子查询拿到去重后的订单数据,再统计运费总和:
SELECT sum(shipping_price) FROM ( SELECT DISTINCT `product_order`.id, `product_order`.shipping_price FROM `product_order` INNER JOIN `product_address` ON `product_order`.`address_id` = `product_address`.`id` INNER JOIN `product_item` ON `product_order`.`id` = `product_item`.`order_id` WHERE (`status`<>2) AND (`company_id`=1968) AND DATE(date)='2021-08-31' ) AS temp_order
这里内层的DISTINCT是针对订单ID去重,只要订单ID不同,哪怕运费值完全相同也会保留记录,求和后就能得到正确的600。
也可以用IN子查询替代,写法更直观:
SELECT sum(shipping_price) FROM `product_order` INNER JOIN `product_address` ON `product_order`.`address_id` = `product_address`.`id` WHERE (`status`<>2) AND (`company_id`=1968) AND DATE(date)='2021-08-31' AND `product_order`.id IN ( SELECT DISTINCT order_id FROM `product_item` -- 此处可添加订单项过滤条件 )
内容的提问来源于stack exchange,提问作者kiamoz
相关产品推荐
相关产品推荐

