SQL如何从另一表插入新行,冲突键保留旧值?
仅插入tb2中tb1不存在的行的正确SQL写法
问题背景
现有两张表tb1和tb2,均以(id, name, date)作为唯一组合键。需要将tb2中tb1没有的行插入tb1,比如只插入tb2里的(1, John, 01/01/2013)(另一行已存在于tb1)。
原SQL的问题
你尝试的语句存在列数不匹配的错误:
INSERT INTO tb1 (date) SELECT * FROM tb2 ON CONFLICT (id,name,date) DO NOTHING;
INSERT INTO tb1 (date)指定只插入date列,但SELECT *会返回id、name、date三列,执行时会因列数量不匹配报错。
正确写法
需要明确指定要插入的所有列(或确保表结构一致时省略列列表),结合ON CONFLICT子句处理唯一键冲突:
写法一(明确指定列,更安全)
INSERT INTO tb1 (id, name, date) SELECT id, name, date FROM tb2 ON CONFLICT (id, name, date) DO NOTHING;
写法二(表结构完全一致时简化)
如果tb1和tb2的列顺序、数量完全相同(都是id、name、date),可以简化为:
INSERT INTO tb1 SELECT * FROM tb2 ON CONFLICT (id, name, date) DO NOTHING;
效果说明
这两个语句都会遍历tb2的所有行,当遇到(id, name, date)组合已存在于tb1的情况时自动跳过,只插入tb1中没有的行,正好满足需求。
内容的提问来源于stack exchange,提问作者moth
相关产品推荐
相关产品推荐

