125

我有以下两个表:

Table1
----------
ID   Name
1    A
2    B
3    C

Table2
----------
ID   Name
1    Z

我需要从 to 插入Table1数据Table2。我可以使用以下语法:

INSERT INTO Table2(Id, Name) SELECT Id, Name FROM Table1

但是,在我的情况下,重复的 ID 可能存在Table2(在我的情况下,它只是“ 1”),我不想再次复制它,因为这会引发错误。

我可以这样写:

IF NOT EXISTS(SELECT 1 FROM Table2 WHERE Id=1)
INSERT INTO Table2 (Id, name) SELECT Id, name FROM Table1 
ELSE
INSERT INTO Table2 (Id, name) SELECT Id, name FROM Table1 WHERE Table1.Id<>1

有没有更好的方法可以在不使用的情况下做到这一点IF - ELSE?我想避免INSERT INTO-SELECT基于某些条件的两个语句。

4

10 回答 10

243

使用NOT EXISTS

INSERT INTO TABLE_2
  (id, name)
SELECT t1.id,
       t1.name
  FROM TABLE_1 t1
 WHERE NOT EXISTS(SELECT id
                    FROM TABLE_2 t2
                   WHERE t2.id = t1.id)

使用NOT IN

INSERT INTO TABLE_2
  (id, name)
SELECT t1.id,
       t1.name
  FROM TABLE_1 t1
 WHERE t1.id NOT IN (SELECT id
                       FROM TABLE_2)

使用LEFT JOIN/IS NULL

INSERT INTO TABLE_2
  (id, name)
   SELECT t1.id,
          t1.name
     FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.id = t1.id
    WHERE t2.id IS NULL

在这三个选项中,LEFT JOIN/IS NULL效率较低。有关详细信息,请参阅此链接。

于 2010-03-25T05:07:34.857 回答
40

在 MySQL 中,您可以这样做:

INSERT IGNORE INTO Table2(Id, Name) SELECT Id, Name FROM Table1

SQL Server 有类似的东西吗?

于 2010-03-25T06:24:56.853 回答
7

我刚刚遇到了类似的问题,DISTINCT 关键字很神奇:

INSERT INTO Table2(Id, Name) SELECT DISTINCT Id, Name FROM Table1
于 2016-07-15T22:10:10.460 回答
5

我最近遇到了同样的问题......
这是MS SQL Server 2017中对我有用的东西......
主键应该设置在表2中的ID上......
列和列属性当然应该在两者之间相同表。这将在您第一次运行以下脚本时起作用。表 1 中的重复 ID,不会插入...

如果你第二次运行它,你会得到一个

违反 PRIMARY KEY 约束错误

这是代码:

Insert into Table_2
Select distinct *
from Table_1
where table_1.ID >1
于 2018-10-20T22:14:53.793 回答
4

在这里使用IanC 建议ignore Duplicates的唯一索引是我对类似问题的解决方案,使用选项创建索引WITH IGNORE_DUP_KEY

In backward compatible syntax
, WITH IGNORE_DUP_KEY is equivalent to WITH IGNORE_DUP_KEY = ON.

参考:index_option

于 2015-01-14T16:41:14.127 回答
4

在 SQL Server 中,您可以在表上为(需要唯一的列)设置唯一键索引

从 sql server 右键单击​​ table design 选择 Indexes/Keys

选择不重复的列,然后输入唯一键

于 2016-07-31T08:09:14.367 回答
2

有点跑题了,但是如果您想将数据迁移到新表,并且可能的重复项在原始表中,并且可能重复的列不是 id,aGROUP BY会这样做:

INSERT INTO TABLE_2
(name)
  SELECT t1.name
  FROM TABLE_1 t1
  GROUP BY t1.name
于 2018-01-30T15:43:17.353 回答
0

在我的例子中,我在源表中有重复的 ID,所以没有一个提议有效。我不在乎性能,它只完成一次。为了解决这个问题,我用光标一一记录以忽略重复项。

所以这里是代码示例:

DECLARE @c1 AS VARCHAR(12);
DECLARE @c2 AS VARCHAR(250);
DECLARE @c3 AS VARCHAR(250);


DECLARE MY_cursor CURSOR STATIC FOR
Select
c1,
c2,
c3
from T2
where ....;

OPEN MY_cursor
FETCH NEXT FROM MY_cursor INTO @c1, @c2, @c3

WHILE @@FETCH_STATUS = 0
BEGIN
    if (select count(1) 
        from T1
        where a1 = @c1
        and a2 = @c2
        ) = 0 
            INSERT INTO T1
            values (@c1, @c2, @c3)

    FETCH NEXT FROM MY_cursor INTO @c1, @c2, @c3
END
CLOSE MY_cursor
DEALLOCATE MY_cursor
于 2020-10-14T19:59:21.893 回答
0

我使用 MERGE 查询来填充没有重复的表。我遇到的问题是表中的双键(代码、值),并且存在的查询非常慢 MERGE 执行得非常快(超过 X100)

MERGE 查询示例

于 2021-04-12T13:25:20.693 回答
-6

一个简单DELETE的之前INSERT就足够了:

DELETE FROM Table2 WHERE Id = (SELECT Id FROM Table1)
INSERT INTO Table2 (Id, name) SELECT Id, name FROM Table1

根据您要保留的表和配对Table1进行切换。Table2Idname

于 2018-11-14T01:43:43.480 回答