如何合并两个同结构表,ID匹配时优先保留Table A数据?
合并两表并保留唯一ID,同ID时优先保留Table A的记录
我有两个结构完全相同的表Table A和Table B,需要合并这两个表并确保每个ID只出现一次。当两个表存在相同ID的记录时,优先保留Table A的记录(包括所有字段,比如示例中ID=A的记录,Table A的Age是33、Source是public,Table B的Age是32、Source是private,结果取Table A的那条)。
我试过用UNION操作,但不知道怎么实现Table A优先的逻辑,求帮助。
表结构及示例数据
Table A
| Id | Name | Age | Source |
|---|---|---|---|
| A | Jack | 33 | public |
| B | Jon | 44 | public |
| C | Tom | 45 | public |
| D | sid | 19 | public |
| A | Jack | 33 | public |
Table B
| Id | Name | Age | Source |
|---|---|---|---|
| A | Jack | 32 | private |
| B | Jon | 44 | private |
| E | Matt | 19 | private |
| F | Tom | 30 | private |
期望结果
| Id | Name | Age | Source |
|---|---|---|---|
| A | Jack | 33 | public |
| B | Jon | 44 | public |
| C | Tom | 45 | public |
| D | sid | 19 | public |
| E | Matt | 19 | private |
| F | Tom | 30 | private |
解决方案
方法1:窗口函数(适配MySQL 8+、PostgreSQL、SQL Server等主流数据库)
先合并两表所有数据,给Table A的记录标记更高优先级,再按ID分组取优先级最高的记录:
WITH combined AS ( SELECT *, 1 AS priority FROM TableA UNION ALL SELECT *, 2 AS priority FROM TableB ), ranked AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY priority) AS rn FROM combined ) SELECT Id, Name, Age, Source FROM ranked WHERE rn = 1;
- 给Table A标记
priority=1、Table B标记priority=2,确保排序时A的记录排在前面 ROW_NUMBER()按ID分组,每个ID组里第一条(rn=1)就是要保留的优先记录- 如果Table A内有重复ID,会自动取组内第一条(示例中两条ID=A的记录完全一致,不影响结果)
方法2:LEFT JOIN + COALESCE(适配不支持窗口函数的老版本数据库)
先取Table A的所有记录,再补充Table B中未在Table A出现过的ID记录:
-- 若Table A本身有重复ID,可加DISTINCT去重 SELECT DISTINCT Id, Name, Age, Source FROM TableA UNION SELECT b.Id, b.Name, b.Age, b.Source FROM TableB b LEFT JOIN TableA a ON b.Id = a.Id WHERE a.Id IS NULL;
UNION会自动去重,确保Table A的重复ID只保留一条- 左连接后筛选
a.Id IS NULL,仅保留Table B中未在Table A出现的ID记录
方法3:NOT IN + UNION(适配SQL Server、PostgreSQL等)
逻辑和方法2一致,用NOT IN替代左连接筛选:
SELECT DISTINCT Id, Name, Age, Source FROM TableA UNION SELECT Id, Name, Age, Source FROM TableB WHERE Id NOT IN (SELECT Id FROM TableA);
内容的提问来源于stack exchange,提问作者Ullan
相关产品推荐
相关产品推荐

