如何用SQL实现两张表的UPSERT:更新tb2并插入tb1缺失数据
SQL实现「插入+更新」(Upsert)的解决方案
嘿,你要的这个需求其实就是SQL里常说的Upsert(更新+插入)操作——把tb1里tb2没有的记录插进去,同时用tb1的数据覆盖tb2里已有的匹配记录。不同数据库的语法略有区别,但核心逻辑一致,我结合你的示例给你讲清楚:
核心逻辑先明确
我们以KEY字段作为匹配依据:
- 如果tb2中已经存在相同
KEY的记录:用tb1的col one和col two更新tb2的对应字段 - 如果tb2中没有该
KEY的记录:直接把tb1的这条记录插入tb2
1. MySQL/MariaDB 实现
MySQL系数据库用INSERT ... ON DUPLICATE KEY UPDATE语法,前提是tb2的KEY字段是主键或唯一索引(不然数据库没法判断“重复”)
INSERT INTO tb2 (`KEY`, `col one`, `col two`) SELECT `KEY`, `col one`, `col two` FROM tb1 ON DUPLICATE KEY UPDATE `col one` = VALUES(`col one`), `col two` = VALUES(`col two`);
执行后,tb2里KEY=2的col two会被更新为change data,KEY=3的记录会被插入,完全符合你的预期。
2. PostgreSQL 实现
PostgreSQL用INSERT ... ON CONFLICT ... DO UPDATE语法,同样需要KEY字段有唯一约束(主键或唯一索引)
INSERT INTO tb2 ("KEY", "col one", "col two") SELECT "KEY", "col one", "col two" FROM tb1 ON CONFLICT ("KEY") DO UPDATE SET "col one" = EXCLUDED."col one", "col two" = EXCLUDED."col two";
这里的EXCLUDED指的是原本要插入但因为冲突被拦截的那条tb1记录,用它的值来覆盖tb2的现有数据。
3. SQL Server 实现
SQL Server用标准SQL的MERGE语句,逻辑更直观,也能在其他支持该语法的数据库(比如Oracle)中使用
MERGE INTO tb2 AS target USING tb1 AS source ON target.[KEY] = source.[KEY] WHEN MATCHED THEN UPDATE SET target.[col one] = source.[col one], target.[col two] = source.[col two] WHEN NOT MATCHED THEN INSERT ([KEY], [col one], [col two]) VALUES (source.[KEY], source.[col one], source.[col two]);
这个语句把tb1作为“源表”,tb2作为“目标表”,通过KEY匹配后分别执行更新或插入操作,逻辑一目了然。
内容的提问来源于stack exchange,提问作者lidorag
相关产品推荐
相关产品推荐

