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

Postgres新增JOIN导致SUM计算结果翻倍问题咨询

为什么第二个SQL查询的SUM结果是预期值的两倍?

这个问题的核心在于多次同表连接导致的行数膨胀,咱们一步步拆解来看:

先看第一个符合预期的查询

SELECT *, SUM(CASE WHEN "token"."name" = '' THEN 5 ELSE 9 END) AS "n" 
FROM "word" 
LEFT OUTER JOIN "token" ON ("word"."id" = "token"."word_id") 
WHERE ("word"."id" = 1) 
GROUP BY "word"."id";

当word.id=1的记录左连接token表时,会得到2条结果行:1条token.name为空,1条token.name非空。SUM计算时就是5+9=14,完全符合你的预期。

再看结果翻倍的第二个查询

SELECT *, SUM(CASE WHEN "token"."name" = '' THEN 5 ELSE 9 END) AS "n" 
FROM "word" 
LEFT OUTER JOIN "token" ON ("word"."id" = "token"."word_id") 
INNER JOIN "token" T3 ON ("word"."id" = T3."word_id") 
WHERE ("word"."id" = 1) 
GROUP BY "word"."id";

问题就出在连续两次连接同一个token表:

  1. 第一步:word左连接token后,得到2条基础行(记为行A:token.name为空;行B:token.name非空)。
  2. 第二步:用这2条基础行再内连接token T3(同样匹配word_id=1),而T3里同样有2条对应记录。这时每一条基础行都会和T3的2条记录匹配,最终生成的行数是2×2=4条:
    • 行A + T3的空值行
    • 行A + T3的非空行
    • 行B + T3的空值行
    • 行B + T3的非空行
  3. 最后SUM计算时,CASE语句会对这4条行分别求值:
    • 行A对应的两条贡献5+5=10
    • 行B对应的两条贡献9+9=18
    • 总和10+18=28,正好是原预期值的两倍。

简单来说,第二次连接token表没有额外过滤条件,只是基于word_id匹配,导致左连接后的每条记录都被重复了token表中对应记录的次数,最终SUM相当于把原来的每个值都加了两次,结果自然翻倍。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:40:07