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

如何基于关联表的唯一ID返回正确的SUM计算结果?

解决SQL中多表关联导致的重复求和问题

嘿,我太懂你这个困扰了——这是SQL新手很容易踩的「重复关联导致求和翻倍」的坑!咱们先把问题根源理清楚:

你的m_user表中,ID=22222对应两条记录(分别是TG和MS平台)。当你把person、m_user、plan三张表直接关联时,plan里的两条记录(72小时和88小时)会分别和m_user的两条记录匹配,相当于生成了4条重复的plan记录:

  • 22222 + 72
  • 22222 + 72
  • 22222 + 88
  • 22222 + 88

这样SUM起来自然就是722 + 882 = 320,而不是你想要的72+88=160。之前尝试的DISTINCT和DISTINCT ON没用,是因为它们是在求和之后生效的,没办法改变已经重复计算的总和。

下面给你几个简单有效的解决方案:

方案1:先聚合plan表,再关联其他表

先把每个用户的计划小时数总和算好,再和用户表关联,从根源避免重复匹配:

SELECT ps.id, ps.name, ps.email, pl.total_hours AS hours
FROM schema.person AS ps
-- 先计算每个id的计划总时长
JOIN (
    SELECT id, SUM(hours) AS total_hours
    FROM schema.plan
    WHERE client = 'CLIENT11' 
      AND date BETWEEN '2017-12-01' AND '2017-12-31'
    GROUP BY id
) AS pl ON ps.id = pl.id
-- 确保该用户存在于m_user表中
WHERE EXISTS (
    SELECT 1 FROM schema.m_user AS usr WHERE usr.id = ps.id
);

方案2:先对m_user的ID去重,再关联

如果想保留三表关联的结构,可以先把m_user里的重复ID去掉,再和其他表关联:

SELECT ps.id, ps.name, ps.email, SUM(pl.hours) AS hours
FROM schema.person AS ps
-- 只取m_user中唯一的ID
JOIN (SELECT DISTINCT id FROM schema.m_user) AS usr ON ps.id = usr.id
JOIN schema.plan AS pl ON usr.id = pl.id
WHERE pl.client = 'CLIENT11' 
  AND pl.date BETWEEN '2017-12-01' AND '2017-12-31'
GROUP BY ps.id, ps.name, ps.email;

方案3:用CTE让逻辑更清晰(PostgreSQL友好)

如果你喜欢更模块化的写法,用CTE把各个步骤拆分出来,可读性更强:

WITH plan_totals AS (
    -- 第一步:计算每个用户的计划总时长
    SELECT id, SUM(hours) AS total_hours
    FROM schema.plan
    WHERE client = 'CLIENT11' 
      AND date BETWEEN '2017-12-01' AND '2017-12-31'
    GROUP BY id
),
unique_user_ids AS (
    -- 第二步:获取m_user中所有唯一的用户ID
    SELECT DISTINCT id FROM schema.m_user
)
-- 第三步:关联用户信息和计算好的总时长
SELECT ps.id, ps.name, ps.email, pt.total_hours AS hours
FROM schema.person AS ps
JOIN unique_user_ids AS uui ON ps.id = uui.id
JOIN plan_totals AS pt ON ps.id = pt.id;

这三个方案都能解决你的问题,其中方案1和3的性能会更好一些,因为提前聚合了plan表,减少了关联的数据量。

内容的提问来源于stack exchange,提问作者M. Montoya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:30:06