在将记录添加到SQL表时检测重复项

时间:2016-01-20 14:17:04

标签: sql join duplicates sql-insert bulkinsert

我有一种奇怪的情况。我试图以递归方式将记录添加到SQL表中。

表结构(简化):

TableA
Key1  Key2 Description

假设我已经用一些记录更新了TableA:

Key1   Key2  Description
12345  98765 Name1
23456  87654 Name2
34567  76543 Name3
45678  65432 Name4

我现在需要通过Key2获取所有记录并在另一个表中查找它们(TableB),但如果Key1和Key2的组合已经存在,我不需要更新TableA。 例如,如果我在TableB中找到Key2 = 87654和Key1 = 15965的记录,我应该按如下方式更新TableA:

Key1   Key2   Description
87654  15965  Name59

但如果我在TableB中找到Key2 = 87654和Key1 = 23456的记录,我就不应该在TableA中创建记录:

Key1  Key2  Description
87654 23456 Name59

以上记录应创建。

这是我的疑问:

insert into TableA
(key1, key2, Description)
select Key1, Key2, Description from TableB
join TableB TableB.Key1 = TableA.key2
and TableB.Key2 <> TableA.Key1
and not exists(select 1 from TableA where TableA.Key2= TableB.Key1and TableA.Key1 = TableB.Key2)

这实际上会插入重复项,所以最后这就是我得到的:

Key1   Key2  Description
12345  98765 Name1
23456  87654 Name2
34567  76543 Name3
45678  65432 Name4
76543  74185 Name5
87654  82563 Name6
87654  23456 Name7
76543  34567 Name8
65432  45678 Name9

我试图避免插入最后3条记录。 任何人都知道我做错了什么?

编辑:只是为了澄清......这是我的数据集:

Key1                                    Key2
E7483934-9AF7-E111-9912-78E7D16510D0    8FDE361D-B5C6-E011-A943-78E7D1644F78
E7483934-9AF7-E111-9912-78E7D16510D0    5001D99D-966B-E111-8FD2-78E7D16510D0
E7483934-9AF7-E111-9912-78E7D16510D0    76E8758E-A366-E111-B7C5-78E7D16510D0
E7483934-9AF7-E111-9912-78E7D16510D0    FB6F054F-E2BE-E511-9410-005056B5201F
E7483934-9AF7-E111-9912-78E7D16510D0    4A2007DA-E2BE-E511-9410-005056B5201F
E7483934-9AF7-E111-9912-78E7D16510D0    AE90299F-FAF5-E211-8706-D8D385B829F8
E7483934-9AF7-E111-9912-78E7D16510D0    76E9758E-A366-E111-B7C5-78E7D16510D0
E7483934-9AF7-E111-9912-78E7D16510D0    EB483934-9AF7-E111-9912-78E7D16510D0
8FDE361D-B5C6-E011-A943-78E7D1644F78    AE90299F-FAF5-E211-8706-D8D385B829F8
8FDE361D-B5C6-E011-A943-78E7D1644F78    EB483934-9AF7-E111-9912-78E7D16510D0
8FDE361D-B5C6-E011-A943-78E7D1644F78    76E9758E-A366-E111-B7C5-78E7D16510D0


AE90299F-FAF5-E211-8706-D8D385B829F8    8FDE361D-B5C6-E011-A943-78E7D1644F78
76E9758E-A366-E111-B7C5-78E7D16510D0    8FDE361D-B5C6-E011-A943-78E7D1644F78
EB483934-9AF7-E111-9912-78E7D16510D0    8FDE361D-B5C6-E011-A943-78E7D1644F78

所以顶部是TableB(我的源表)。 我需要通过特定的Key1值查看此表(比如WHERE TableB.key1 =&#39; E7483934-9AF7-E111-9912-78E7D16510D0&#39;),将带有该值的记录拉入另一个表(TableA),然后再次查找TableB,但是通过TableB.key1 = TableA.key2,如果存在记录,则将它们添加到TableA表中。需要注意的是,我不希望TableA具有key1 + key2的相同组合。因此,如果你看一下上面的例子,我只希望将前11条记录拉入TableA,但它还会引入我不需要的最后3条记录,因为这些组合已经存在于TableA中。

TIA,
-Tony.

2 个答案:

答案 0 :(得分:1)

您可以使用join子句中的条件不插入不需要的记录。

insert into TableA
(key1, key2, Description)
select b.key1, b.key2, b.description 
from TableB b
join TableA a on (b.key1 <> a.key1 and b.key1 <> a.key2)
              or (b.key2 <> a.key1 and b.key2 <> a.key2)

答案 1 :(得分:0)

不要使用联接,或仅使用它们来否定您要插入的记录。

使用联接时,数据库将从TableB获取所有记录,与TableA的每个记录进行比较,如果有一个记录验证它,则它将通过。按照您的示例,可以通过表A的第一行验证不需要的行(例如,在您的示例中,您甚至将TableB与TableB连接...我假设连接是TableA)。

不根据您的查询使用联接:

insert into TableA
(key1, key2, Description)
select Key1, Key2, Description from TableB as B
where not exists(select 1 from TableA as A where A.Key2=B.Key1 and A.Key1=B.Key2)

或使用联接来否定/阻止不需要的行:

insert into TableA
(Key1, Key2, Description)
select distinct B.Key1, B.Key2, B.Description 
from TableB as B
left outer join TableA as A on A.Key2=B.Key1 and A.Key1=B.Key2
where A.Key1 is null

考虑到Key1可能不为null。还可以使用distinct来防止复制匹配多行的记录。