带非空过滤的Left Join SQL查询返回无行?如何获取Nationality表的客户国籍
为什么左连接加右表非空过滤后查不到数据
左连接加右表非空条件的逻辑本质
- 左连接(Left Join)的默认执行效果是:无论右表是否能匹配上连接条件,都会把左表的所有记录保留下来,右表匹配失败的行,对应的所有右表列都会被填充为NULL。
- 当你在WHERE子句里加上
IWZ.NATIONALITY is not null的过滤条件,本质上是把所有右表匹配失败(也就是列值为NULL)的行全部删掉,这个时候整个查询的实际执行效果和内连接(Inner Join)完全一致,根本没有左连接“保留无匹配左表记录”的作用了。
当前查询返回0行的核心原因
因为改造后的内连接逻辑没有找到任何满足连接条件的匹配行,常见的触发场景有这几种:
- 右表
iwz_nationality本身是空表,没有任何国籍的基础数据 - 两张表的
NATIONALITY字段存在肉眼看不到的字符差异:比如值前后带隐藏空格、换行符、全角半角字符,哪怕你看着两个值一模一样,经过UPPER()转换后的实际字符串值也不相等,没法匹配上 - 左表
MBTC_DEV_CLIENT_MAST_VIEW里的NATIONALITY字段全是NULL,而SQL里NULL和任何值做等值判断的结果都是UNKNOWN,永远不可能匹配成功 - 两张表的国籍值根本不在一个编码体系里:比如左表存的是中文“中国”,右表存的是ISO两位代码“CN”,两个字段的值域完全没有交集,自然一行都匹配不上
对应需求的正确写法
你要的是获取存在于国籍表中的客户国籍信息,完全可以直接用内连接写,逻辑更清晰,同时加上TRIM()处理常见的隐藏空格问题,参考SQL:
select CMV.CLIENT_CMF, IWZ.NATIONALITY from MBTC_DEV_CLIENT_MAST_VIEW CMV inner join iwz_nationality IWZ on UPPER(TRIM(CMV.NATIONALITY)) = UPPER(TRIM(IWZ.NATIONALITY))
如果要排查匹配失败的问题,可以按顺序查:
- 先看国籍基础表有没有数据:执行
select count(*) from iwz_nationality,如果返回0,就是基础数据没导入 - 抽样对比两表的实际存储值:分别取左表的几个非空国籍值、右表的国籍值,核对是不是存在值域不匹配、隐藏字符的问题
- 确认左表国籍字段的非空率:执行
select count(*) from MBTC_DEV_CLIENT_MAST_VIEW where NATIONALITY is not null,如果结果是0,说明左表根本没有有效的国籍数据
内容的提问来源于stack exchange,提问作者Jakey
相关产品推荐
相关产品推荐

