LEFT JOIN统计时排除左表重复计数的SQL问题求解
解决订单统计重复计数的问题
你遇到的问题很典型:当用左连接关联两张表时,table1中符合条件的单个订单(比如order_id=3)会因为table2里对应的多条产品记录被重复展开,导致计数时把重复的行也算进去了——用户ID1的两个有效订单最终变成了3行数据,所以COUNT结果就错了。
这里有两种靠谱的解决方案:
方案一:快速修复——用COUNT(DISTINCT)去重计数
既然我们要统计的是唯一的有效订单数量,而不是连接后的行数,直接在COUNT里加上DISTINCT关键字,对order_id去重即可:
SELECT h.user_id, COUNT(DISTINCT h.order_id) AS total_orders, SUM(o.quantity) AS quantity FROM table1 h LEFT JOIN table2 o ON o.order_id = h.order_id WHERE h.order_status = 5 GROUP BY h.user_id
这个改动很小,适合快速解决问题,小数据量下性能也没问题。
方案二:更高效的先聚合再关联
如果你的数据量比较大,先分别对两张表做聚合再关联会更高效(避免不必要的笛卡尔积):
- 先统计
table2中每个订单的总销量; - 再从
table1筛选出状态为5的订单,和第一步的结果关联后按用户聚合。
WITH order_quantities AS ( -- 先计算每个订单的总数量 SELECT order_id, SUM(quantity) AS order_total_qty FROM table2 GROUP BY order_id ), valid_orders AS ( -- 筛选出所有状态为5的订单及对应用户 SELECT user_id, order_id FROM table1 WHERE order_status = 5 ) SELECT vo.user_id, COUNT(vo.order_id) AS total_orders, SUM(oq.order_total_qty) AS quantity FROM valid_orders vo LEFT JOIN order_quantities oq ON vo.order_id = oq.order_id GROUP BY vo.user_id
这个方法从根源上避免了订单行被重复展开的问题,计数自然不会出错,同时因为提前聚合了数据,连接时处理的数据量更小,性能更优。
两种方案都能得到你期望的结果:user1的有效订单数为2,总数量15;user2的有效订单数为1,总数量4。
内容的提问来源于stack exchange,提问作者Moiz Ahmad
相关产品推荐
相关产品推荐

