如果记录存在,则更新,否则插入

10

我想在两个SQL Server 2008表之间移动一些数据。如果Table2中存在与Table1的电子邮件相同的记录,则使用来自Table1的数据更新该记录,否则插入一个新记录。

在Table1中,我有许多列,例如名字、姓氏、电子邮件等。

我不确定如何构建查询以更新Table2(如果来自Table1的电子邮件存在)或插入新行(如果Table1的电子邮件在Table2中不存在)。

我尝试在Google上搜索了一些内容,但大多数解决方案似乎都是通过创建存储过程来实现的。因此,我想知道是否有人知道如何构建适当的查询来完成这个目标?

3个回答

21

我想MERGE是你想要的。


这正是MERGE的设计初衷...(有些领域甚至称之为"UPSERT",尽管它处理的不仅仅是INSERT/UPDATE)。 - Aaron Bertrand

13
MERGE
INTO    table2 t2
USING   table1 t1
ON      t2.email = t1.email
WHEN MATCHED THEN
UPDATE
SET     t2.col1 = t1.col1,
        t2.col2 = t1.col2
WHEN NOT MATCHED THEN
INSERT  (col1, col2)
VALUES  (t1.col1, t1.col2)

1

微软发布了一款比较SQL表格数据的工具,在某些情况下这可能是一个不错的选择。

编辑:忘记提到了,它还生成一个脚本来插入/更新缺失或不同的行。

为了完整起见,我编写了这个查询,它可以更新现有的table2记录,并添加那些基于电子邮件地址缺失的记录。

下面的“更新”和“插入缺失”的查询是你想要的。

BEGIN TRAN

create table #table1 (id int, fname varchar(20), email varchar(20))
insert into #table1 values (1, 'name_1_updated', 'email_1')
insert into #table1 values (3, 'name_3_updated', 'email_3')
insert into #table1 values (100, 'name_100', 'email_100')


create table #table2 (id int, fname varchar(20), email varchar(20))
insert into #table2 values (1, 'name_1', 'email_1')
insert into #table2 values (2, 'name_2', 'email_2')
insert into #table2 values (3, 'name_3', 'email_3')
insert into #table2 values (4, 'name_4', 'email_4')

print 'before update'
select * from #table2

print 'updating'
update #table2
set #table2.fname = t1.fname
from #table1 t1
where t1.email = #table2.email

print 'insert missing'
insert into #table2
select * from #table1
where #table1.email not in (select email from #table2 where email = #table1.email)

print 'after update'
select * from #table2

drop table #table1
drop table #table2

ROLLBACK

兄弟,感谢你花时间编写上述查询。非常感谢...我会尝试一下。 - doubleplusgood
这是针对使用 SQL 2008 之前版本的人,因为 MERGE 命令只支持 SQL 2008。他们从 RTM 版本中删除了它。愚蠢的 SQL 团队。 - invert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接