SQL中UNION操作时填充NULL值并合并重复员工记录的方法
合并员工表并填充NULL值的通用SQL方案
我有两个结构完全一致的员工表Table1和Table2,数据如下:
Table1 数据
| EmployeeID | FirstName | LastName | Gender | Age |
|---|---|---|---|---|
| A100 | Bob | Odenkirk | Male | 30 |
| A101 | Jon | Jones | NULL | 36 |
Table2 数据
| EmployeeID | FirstName | LastName | Gender | Age |
|---|---|---|---|---|
| A101 | Jon | Jones | Male | NULL |
| A103 | Angelina | Jolie | Female | 40 |
最初尝试用UNION合并两个表:
SELECT * FROM Table1 UNION SELECT * FROM Table2
但因为NULL被视为不同值,导致重复的A101记录无法合并,结果如下:
| EmployeeID | FirstName | LastName | Gender | Age |
|---|---|---|---|---|
| A100 | Bob | Odenkirk | Male | 30 |
| A101 | Jon | Jones | NULL | 36 |
| A101 | Jon | Jones | Male | NULL |
| A103 | Angelina | Jolie | Female | 40 |
需要一种通用方案(适用于大型表,无需提前知晓哪些字段存在缺失),合并后填充NULL值,得到如下目标结果:
| EmployeeID | FirstName | LastName | Gender | Age |
|---|---|---|---|---|
| A100 | Bob | Odenkirk | Male | 30 |
| A101 | Jon | Jones | Male | 36 |
| A103 | Angelina | Jolie | Female | 40 |
通用解决方案
核心逻辑:先合并两个表的所有数据(保留重复行),再按员工唯一标识EmployeeID分组,对每个字段提取非NULL的有效值。
MAX()函数会自动忽略NULL,且适配字符串、数值等绝大多数字段类型,是最通用的聚合方式:
SELECT EmployeeID, MAX(FirstName) AS FirstName, MAX(LastName) AS LastName, MAX(Gender) AS Gender, MAX(Age) AS Age FROM ( -- 合并两个表的所有数据,包含重复行 SELECT * FROM Table1 UNION ALL SELECT * FROM Table2 ) AS combined_data GROUP BY EmployeeID
方案细节说明
- 用
UNION ALL替代UNION:UNION会先去重再返回结果,而我们需要保留所有行来提取每个字段的非NULL值,UNION ALL更高效且符合需求。 - 按
EmployeeID分组:确保每个员工最终只保留一条记录。 MAX()的作用:对任意字段,只要存在非NULL值,MAX()就会返回该有效值;若该字段所有行都是NULL,则返回NULL(符合业务逻辑)。
此方案无需提前指定哪些字段有缺失,无论表有多少字段,只需按主键分组并对每个字段应用MAX()即可,完全适配大型表场景。
内容的提问来源于stack exchange,提问作者mosefaq
相关产品推荐
相关产品推荐

