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

多表关联查询中SUM忽略DISTINCT导致计算值错误问题

解决一对多关联下SUM主表字段重复计算的问题

问题根源

ordem_servico与fluxo_servico_time是一对多关联关系,关联查询时主表的单条记录会被子表的多条记录重复带出,直接对ordem_servico.cm_total求和会导致同一主表记录的数值被多次累加,最终结果偏大。

可行解决方案

方案1:先聚合主表,再关联子表

先单独计算主表的SUM值,再和子表的统计结果关联,从根源避免重复累加:

SELECT 
    fst.qty,
    fst.user_id,
    os.total_cm
FROM (
    -- 先计算主表的正确总和
    SELECT SUM(cm_total) AS total_cm
    FROM ordem_servico
    -- 可添加主表过滤条件
) os
JOIN (
    -- 子表单独统计需要的qty、user_id
    SELECT 
        COUNT(*) AS qty,
        user_id
    FROM fluxo_servico_time
    -- 关联主表的外键过滤(按需添加)
    WHERE ordem_servico_id IN (SELECT id FROM ordem_servico)
    GROUP BY user_id
) fst ON 1=1
WHERE fst.user_id = 5;

方案2:用子查询独立计算主表总和

在SELECT语句中通过子查询单独计算主表的SUM值,不受关联后的重复记录影响:

SELECT 
    COUNT(fst.id) AS qty,
    fst.user_id,
    -- 子查询直接计算主表的正确总和
    (SELECT SUM(cm_total) FROM ordem_servico) AS total_cm
FROM fluxo_servico_time fst
WHERE fst.user_id = 5
GROUP BY fst.user_id;

如果需要按单条主表记录关联统计,可给子查询添加WHERE id = fst.ordem_servico_id条件。

方案3:基于主表主键去重求和

若必须在关联查询中求和,可利用主表唯一主键确保每条记录只被计算一次:

SELECT 
    COUNT(fst.id) AS qty,
    fst.user_id,
    -- 用主键+数值的唯一组合去重后计算总和
    SUM(DISTINCT os.id * os.cm_total) / SUM(DISTINCT os.id) AS total_cm
FROM ordem_servico os
JOIN fluxo_servico_time fst ON os.id = fst.ordem_servico_id
WHERE fst.user_id = 5
GROUP BY fst.user_id;

原理是通过主键与数值的乘积保证唯一性,求和后除以去重后的主键总数,还原正确的总和。

效果验证

以上方案均可避免主表记录的重复累加,根据实际业务的过滤、分组需求选择对应写法后,即可得到正确的total CM值4328。

内容的提问来源于stack exchange,提问作者Andrei Brayer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:07:06