如何避免Left Join返回结果行数多于原表实际行数?
Left Join后行数超出左表的问题解决
问题原因
你的LEFT JOIN返回31条记录而非预期的29条,核心原因是右表account中存在多条与左表transaction某条记录的a1值匹配的记录。左表的单条记录会被右表的多条匹配记录重复展开,导致总条数增加(29条基础记录 + 2条重复展开的记录 = 31条)。
另外,原查询的CASE语句存在语法错误:第一个WHEN分支结尾误用了逗号,需改为WHEN关键字,修正后的结构见下文示例。
解决方案
要保持左表的29条记录,需确保右表的匹配结果唯一,以下是两种可行方案:
方案1:对右表去重后再关联
通过子查询对account表按b1去重,确保每个b1值对应唯一的b2、b3记录,再与左表关联:
SELECT table1.a1, table1.a2, table1.a3, table1.a4, table2.b1, table2.b2, table2.b3, CASE WHEN table1.a1 IS NOT NULL THEN ROUND(table1.a1, 2) WHEN table2.b1 IS NOT NULL THEN ROUND(table2.b1, 2) ELSE 0 END AS amount FROM transaction table1 LEFT JOIN ( SELECT DISTINCT b1, b2, b3 FROM account ) table2 ON table1.a1 = table2.b1 WHERE table1.external_status IN ('A','F')
方案2:对右表按关联键聚合后再关联
如果account表中同一b1对应多条b2、b3,可根据业务需求用聚合函数(如MAX/MIN)取唯一值,再关联左表:
SELECT table1.a1, table1.a2, table1.a3, table1.a4, table2.b1, table2.b2, table2.b3, CASE WHEN table1.a1 IS NOT NULL THEN ROUND(table1.a1, 2) WHEN table2.b1 IS NOT NULL THEN ROUND(table2.b1, 2) ELSE 0 END AS amount FROM transaction table1 LEFT JOIN ( SELECT b1, MAX(b2) AS b2, -- 根据业务场景选择合适的聚合逻辑 MAX(b3) AS b3 FROM account GROUP BY b1 ) table2 ON table1.a1 = table2.b1 WHERE table1.external_status IN ('A','F')
额外提示
- 若仅需判断
account表中是否存在匹配记录,而非获取b2、b3字段,可改用EXISTS子查询,避免行数膨胀。 - 执行关联前,可先运行
SELECT b1, COUNT(*) FROM account GROUP BY b1 HAVING COUNT(*) > 1,确认哪些b1值对应多条记录,便于针对性处理。
内容的提问来源于stack exchange,提问作者SQL04
相关产品推荐
相关产品推荐

