Left Join子查询结果行数多于主表问题求助
问题诊断与解决方案
嘿,我来帮你拆解下这个问题——你遇到的Left Join后结果行数超过主表的情况其实挺常见的,核心原因出在你的子查询A里。
为什么行数会变多?
你主表PROD.V_FICH_ID_BEN_CM加了WHERE条件后有N行,但Left Join之后行数超过N,是因为子查询A里同一个benbanls(受益人ID)对应了多条不同的date_ch记录。
虽然你在子查询里加了distinct,但这个distinct是对benbanls + date_ch的组合去重的。举个例子:如果某个受益人有3次不同的入院记录(对应3个不同的date_ch),子查询A里会保留这3行。当你用Left Join关联主表时,主表中这个受益人的那一行会和子查询里的3行分别匹配,最终结果里就会出现3条几乎一模一样的主表数据(除了date_chsld不同),自然总行数就超过主表了。
怎么解决?
你得先明确业务需求:对于每个受益人,你想保留子查询里的哪一个date_ch?是最新的、最早的,还是随便哪一个?根据需求选对应的方法就行:
方案1:保留最新的入院日期
把子查询改成按受益人分组,取最大的date_ch,确保每个受益人只返回一行:
select distinct VBen.BENF_NO_INDIV_BEN_BANLS as benbanls, VBen.BENF_COD_SEXE AS Sexe, VBen.BENF_DAT_NAISS AS DatNaiss, VBen.BENF_DAT_DECES AS DatDec, A.date_ch as date_chsld from PROD.V_FICH_ID_BEN_CM AS VBen left join ( select VAss.BENF_NO_INDIV_BEN_BANLS as benbanls, MAX(vass.BENF_DD_ADMIS_ASSU_MED) as date_ch -- 取最新的日期 from Prod.V_ADMIS_ASSU_MED_PLAN_PRIOR_CM as vass group by VAss.BENF_NO_INDIV_BEN_BANLS ) as A on VBen.BENF_NO_INDIV_BEN_BANLS = A.benbanls where Vben.BENF_DAT_NAISS>'2016-04-01' or Vben.BENF_DAT_DECES>'2011-04-01'
方案2:保留最早的入院日期
把上面的MAX换成MIN就可以了:
select distinct VBen.BENF_NO_INDIV_BEN_BANLS as benbanls, VBen.BENF_COD_SEXE AS Sexe, VBen.BENF_DAT_NAISS AS DatNaiss, VBen.BENF_DAT_DECES AS DatDec, A.date_ch as date_chsld from PROD.V_FICH_ID_BEN_CM AS VBen left join ( select VAss.BENF_NO_INDIV_BEN_BANLS as benbanls, MIN(vass.BENF_DD_ADMIS_ASSU_MED) as date_ch -- 取最早的日期 from Prod.V_ADMIS_ASSU_MED_PLAN_PRIOR_CM as vass group by VAss.BENF_NO_INDIV_BEN_BANLS ) as A on VBen.BENF_NO_INDIV_BEN_BANLS = A.benbanls where Vben.BENF_DAT_NAISS>'2016-04-01' or Vben.BENF_DAT_DECES>'2011-04-01'
方案3:任意保留一个日期(不关心先后)
用窗口函数ROW_NUMBER()给每个受益人的记录打标记,只保留第一条:
select distinct VBen.BENF_NO_INDIV_BEN_BANLS as benbanls, VBen.BENF_COD_SEXE AS Sexe, VBen.BENF_DAT_NAISS AS DatNaiss, VBen.BENF_DAT_DECES AS DatDec, A.date_ch as date_chsld from PROD.V_FICH_ID_BEN_CM AS VBen left join ( select VAss.BENF_NO_INDIV_BEN_BANLS as benbanls, vass.BENF_DD_ADMIS_ASSU_MED as date_ch, ROW_NUMBER() OVER(PARTITION BY VAss.BENF_NO_INDIV_BEN_BANLS ORDER BY (SELECT NULL)) as rn from Prod.V_ADMIS_ASSU_MED_PLAN_PRIOR_CM as vass ) as A on VBen.BENF_NO_INDIV_BEN_BANLS = A.benbanls where (Vben.BENF_DAT_NAISS>'2016-04-01' or Vben.BENF_DAT_DECES>'2011-04-01') and A.rn = 1 -- 只保留每个受益人的第一条记录
快速验证问题根源
你可以先跑下面的查询,看看是不是真的存在一个受益人对应多条记录的情况:
select BENF_NO_INDIV_BEN_BANLS, COUNT(*) as record_count from Prod.V_ADMIS_ASSU_MED_PLAN_PRIOR_CM group by BENF_NO_INDIV_BEN_BANLS having COUNT(*) > 1
如果这个查询返回结果,那就能实锤了——这些重复的受益人记录就是Left Join后行数增加的罪魁祸首。
内容的提问来源于stack exchange,提问作者Houssem Missaoui
相关产品推荐
相关产品推荐

