两个同源SQL查询使用UNION合并后行数异常问题咨询
UNION合并后行数变化的原因
核心原因是UNION的全局去重逻辑,而非子查询本身的执行结果发生了变化:
UNION的处理流程是:先拉取两个子查询的全部返回结果,合并为一个临时结果集,再对临时结果集做整行全字段去重,最终返回去重后的结果。你观察到的“子查询返回行数减少”,实际是重复行被全局去重后,两个子查询各自贡献的唯一行计数,而非子查询本身执行时返回的行数变少。
具体对应你的场景
你单独运行两个子查询时,每个子查询的distinct已经保证了子查询内部没有重复的(账号, 标识)二元组,各返回1953行;合并后出现的差值就是两个子查询之间的重复行数:
- 第一个子查询有
1953 - 1816 = 137行和第二个子查询的行完全重复,被全局去重删除 - 第二个子查询有
1953 - 1922 = 31行和第一个子查询的行完全重复,被全局去重删除
验证方案
你可以将UNION替换为UNION ALL运行:UNION ALL不会做全局去重,返回的总行数一定是两个子查询单独运行的行数之和1953 + 1953 = 3906,即可验证上述逻辑正确。
额外注意
如果存在同一个账号在两个子查询中返回不同的标识值(比如同一个账号在第一个子查询返回1,第二个返回0),这两行不会被判定为重复,UNION会同时保留这两条行。如果你需要每个账号仅保留唯一一条结果,需要额外加逻辑判断标识的优先级。
你提供的SQL代码参考:
select distinct acct#, case when (lastFilledDate is not null and lastFilledDate<>'00/00/00') or ([Last Filled DC] is not null and [Last Filled DC]<>'00/00/00') or (vivitrol is not null and vivitrol <>'00/00/00') or (sublocade is not null and sublocade <>'00/00/00') or (naltrexone is not null and naltrexone <>'00/00/00') then 1 else 0 end as result from ( select Acct#, DOB, [COE Contact Note], [COE-INTAKA Doc], [COE-MOM Doc], lastFilledDate, [Last Filled DC],vivitrol,sublocade,naltrexone, ROW_NUMBER() over (partition by Acct# order by [COE-INTAKA Doc] desc) as apptRows from tblAppBSCImportDashCOE2279 as main where (([COE-MOM Doc]='Yes' and [COE Contact Note] is not null) or [COE-MOM Doc]='No') and Appt is not null ) as sub where apptRows=1 union select distinct acctNo, case when providerMAT='The Wright Center' and [COE-MOM Doc] is not null then 1 else 0 end as result from ( select acctNo, [COE-MOM Doc], MAT, providerMAT, ROW_NUMBER() over (partition by acctNo order by COEBNMOM, [COE-MOM Doc] desc) as apptRows from tblAppBSCImportDashCOEHM2544 as main where [COE-MOM Doc] is not null or COEBNMOM is not null ) as sub where apptRows=1
内容的提问来源于stack exchange,提问作者Sara K
相关产品推荐
相关产品推荐

