You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

这个改动很小,适合快速解决问题,小数据量下性能也没问题。

方案二:更高效的先聚合再关联

如果你的数据量比较大,先分别对两张表做聚合再关联会更高效(避免不必要的笛卡尔积):

  1. 先统计table2中每个订单的总销量;
  2. 再从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:54:30