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

多表LEFT JOIN求和出现重复值问题求助(涉及4张业务表)

兄弟,你遇到的这个问题太典型了——多表LEFT JOIN后求和出现重复,本质是一对多关联导致的行膨胀:比如当tb_satker和tb_target是一对多关系时,主表的一条记录会被关联的子表数据重复带出,直接求和就会把数值反复计算,结果自然偏大。我结合你给出的表结构,给你两个最实用的解决方案:

解决方案一:先聚合子表,再关联主表(最推荐)

核心思路是:先对每个存在一对多关系的子表,按关联键(比如kode_satker)单独做聚合运算,得到每个kode_satker的唯一求和结果,再和主表tb_satker关联。这样就从根源上避免了行重复。

举个具体的SQL例子(假设还有另外两张表tb_actual和tb_budget,结构类似tb_target):

SELECT
  s.kode_satker,
  s.nama_satker,
  -- 用COALESCE处理无关联数据的情况,返回0而非NULL
  COALESCE(t.sum_target, 0) AS total_target,
  COALESCE(a.sum_actual, 0) AS total_actual,
  COALESCE(b.sum_budget, 0) AS total_budget
FROM tb_satker s
-- 先聚合tb_target的数据
LEFT JOIN (
  SELECT kode_satker, SUM(jumlah) AS sum_target
  FROM tb_target
  GROUP BY kode_satker
) t ON s.kode_satker = t.kode_satker
-- 同理聚合其他子表
LEFT JOIN (
  SELECT kode_satker, SUM(actual_jumlah) AS sum_actual
  FROM tb_actual
  GROUP BY kode_satker
) a ON s.kode_satker = a.kode_satker
LEFT JOIN (
  SELECT kode_satker, SUM(budget_jumlah) AS sum_budget
  FROM tb_budget
  GROUP BY kode_satker
) b ON s.kode_satker = b.kode_satker;

解决方案二:用DISTINCT+窗口函数(适合需要保留明细的场景)

如果你需要同时查看子表的明细数据,又要得到正确的求和结果,可以用窗口函数结合DISTINCT,确保每个kode_satker只返回一次求和值:

SELECT DISTINCT
  s.kode_satker,
  s.nama_satker,
  t.id AS target_id,
  t.jumlah AS target_jumlah,
  -- 按kode_satker分区求和,确保每个分组的求和值唯一
  SUM(t.jumlah) OVER (PARTITION BY s.kode_satker) AS total_target
FROM tb_satker s
LEFT JOIN tb_target t ON s.kode_satker = t.kode_satker;

关键注意事项

  • 不要直接关联多个未聚合的一对多子表:比如同时关联tb_target和tb_actual(都是一对多),会导致两张子表的数据产生笛卡尔积,行膨胀会更严重,求和结果偏差更大。
  • 验证聚合结果:执行子查询单独查看聚合后的行数,确保每个kode_satker只有一条记录,这样关联后就不会出现重复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:27:41