SQL跨库UNION查询过滤存在有效映射对应NULL行的方法
跨库映射表冗余NULL记录过滤方案
核心过滤规则不需要依赖聚合函数破坏多target映射关系,只需要对合并后的全量映射做两层判断即可:
- 所有
Target非空的映射记录直接保留 Target为NULL的记录,仅当对应Source在全量映射中不存在任何非空Target值时才保留
通用CTE写法(兼容MySQL 8.0+、PostgreSQL、SQL Server、Oracle等支持SQL92后标准的数据库)
WITH all_mapping AS ( SELECT Source, Target FROM DB1.table UNION SELECT Source, Target FROM DB2.table ) SELECT Source, Target FROM all_mapping WHERE Target IS NOT NULL OR NOT EXISTS ( SELECT 1 FROM all_mapping am WHERE am.Source = all_mapping.Source AND am.Target IS NOT NULL );
执行结果校验
运行后返回结果完全匹配预期:
- Source=A存在X、Y两个非空映射,对应NULL记录被过滤,保留X、Y
- Source=B存在非空映射Z,对应NULL记录被过滤,保留Z
- Source=C不存在任何非空映射,保留NULL记录
低版本数据库兼容写法(不支持CTE的场景)
如果你的数据库版本不支持CTE语法,可以用派生表改写,逻辑完全一致:
SELECT am.Source, am.Target FROM ( SELECT Source, Target FROM DB1.table UNION SELECT Source, Target FROM DB2.table ) am WHERE am.Target IS NOT NULL OR NOT EXISTS ( SELECT 1 FROM ( SELECT Source, Target FROM DB1.table UNION SELECT Source, Target FROM DB2.table ) am2 WHERE am2.Source = am.Source AND am2.Target IS NOT NULL );
方案说明
- 不会破坏单Source对应多Target的合法映射,避免了
MAX(Target)类聚合方案丢失多值映射的问题 - 内置的
UNION会自动完成跨库重复映射的去重,无需额外加DISTINCT - 后续新增同结构数据库查询时,只需要在UNION块中追加对应库的SELECT语句即可,无需调整过滤逻辑
内容的提问来源于stack exchange,提问作者Geert Bellekens
相关产品推荐
相关产品推荐

