You need to enable JavaScript to run this app. 如何避免Left Join查询返回的记录数多于主表原始记录数?
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Left Join查询返回的记录数多于主表原始记录数?

问题原因

记录数变多的根本原因是左连接的特性:右表如果存在多个和关联键匹配的行,每多一个匹配项就会生成一行新的结果。你新增关联table_d的时候用table_b.id作为关联键,只要有一个table_b.id在table_d里存在n条匹配记录,原本的1行结果就会拆成n行,总记录数自然就超过了主表table_a的11000条。
另外你写的新增左连接的SQL存在语法错误:Left Join table_d.id是错误写法,正确的关联表语法应该是LEFT JOIN table_d ON table_b.id = table_d.id。

解决方法
  • 方法1:先对table_d做预聚合,保证每个关联id仅对应1行后再关联
    如果你需要取table_d的sales字段,可先按照关联键id对table_d做聚合处理,确保单id唯一,再执行左连接。比如你需要统计每个id的销售总额,可按如下方式改写:
    SELECT table_a.id, table_b.location, table_c.material, d.total_sales
    FROM table_a
    LEFT JOIN table_b ON table_a.id = table_b.id
    LEFT JOIN table_c ON table_a.id = table_c.id
    LEFT JOIN (
      SELECT id, SUM(sales) AS total_sales 
      FROM table_d 
      GROUP BY id
    ) d ON table_b.id = d.id
    
    如果你需要取最新的单条sales,也可以用窗口函数先对table_d做行过滤:
    SELECT table_a.id, table_b.location, table_c.material, d.sales
    FROM table_a
    LEFT JOIN table_b ON table_a.id = table_b.id
    LEFT JOIN table_c ON table_a.id = table_c.id
    LEFT JOIN (
      SELECT id, sales,
      ROW_NUMBER() OVER (PARTITION BY id ORDER BY 你的时间排序字段 DESC) AS rn
      FROM table_d
    ) d ON table_b.id = d.id AND d.rn = 1
    
  • 方法2:用关联子查询替代左连接,避免生成额外行
    如果你仅需要从table_d取单个字段的值,可以直接在SELECT子句中写关联子查询,不会触发左连接的行复制逻辑:
    SELECT 
      table_a.id, 
      table_b.location, 
      table_c.material,
      (SELECT sales FROM table_d WHERE table_d.id = table_b.id ORDER BY 你的排序字段 LIMIT 1) AS sales
    FROM table_a
    LEFT JOIN table_b ON table_a.id = table_b.id
    LEFT JOIN table_c ON table_a.id = table_c.id
    
  • 方法3:排查table_d的脏数据
    如果你的业务逻辑中table_d的id字段应该是唯一主键,那多余的500条记录大概率是table_d存在重复id的脏数据,先清理重复数据后再关联即可保证总记录数和table_a一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 02:09:01