问题说明

遇到的情况类似于包含某商品的店铺订单总金额,订单明细表 -> 订单表关系为 n:1。如果明确商品 ID,可以将明细表与订单表关系约束为 1:1,这样计算的订单总金额就不会存在重复统计。

但当前需要统计多个商品,这样如果直接通过多表联查并聚合统计店铺订单总金额就会存在重复统计的问题。

当然可以直接绕过商品明细表,直接计算商铺订单总金额,但这样无法对商品进行约束。

解决

网络上有针对单表查询重复记录的:

使用 NOT EXISTS 参数

SELECT id, sid FROM table_name a WHERE NOT EXISTS (SELECT 1 FROM table_name where a.sid = sid AND a.create_time < create_time) 

使用子查询

SELECT id, sid FROM table_name WHERE create_time IN (SELECT max(create_time) FROM table_name group by sid)

但并不好直接套用到现在情况。

初始的 sql 语句

SELECT orders.shop_id, FORMAT(COALESCE(SUM(orders.money), 0), 2) total FROM order_detail
INNER JOIN orders ON orders.id = order_detail.order_id
WHERE orders.status = 3 AND order_detail.goods_id in (1,2,3,4,5,6)
GROUP BY orders.shop_id
HAVING total > 0
ORDER BY SUM(orders.money) DESC

计算结果明显是存在重复统计的情况的。

整了半天,最后想到还是两步走,先查出所有包含商品的订单,group by 去重

SELECT orders.shop_id, orders.money FROM order_detail
INNER JOIN orders ON orders.id = order_detail.order_id
WHERE orders.status = 3 AND order_detail.goods_id in (1,2,3,4,5,6)
GROUP BY order_detail.order_id

然后再去统计商铺订单总金额:

SELECT shop_id, FORMAT(COALESCE(SUM(money), 0), 2) total FROM (
SELECT orders.shop_id, orders.money FROM order_detail
INNER JOIN orders ON orders.id = order_detail.order_id
WHERE orders.status = 3 AND order_detail.goods_id in (1,2,3,4,5,6)
GROUP BY order_detail.order_id) shop_order
GROUP BY shop_id
HAVING total > 0
ORDER BY SUM(money) DESC