仅当行不存在时才插入 SQL
Posted
技术标签:
【中文标题】仅当行不存在时才插入 SQL【英文标题】:SQL Insert Only If Row is Not Present 【发布时间】:2017-02-13 20:42:26 【问题描述】:我有以下数据表。
表_1
ID, GROUP_ID, ARTIFACT_ID, VERSION
101, com.abc, pqra, 1.0.0
102, com.abc, pqrb, 2.0.0
103, com.abc, pqrc, 3.0.0
104, com.abc, pqrd, 4.0.0
表_2
ID, MODULE_ID, ISSUE_KEY
11, 104, XYZ-12
12, 104, XYZ-34
我正在使用以下命令在 Table_2 中插入值。
INSERT INTO Table_2 (MODULE_ID, ISSUE_KEY) SELECT ID, 'XYZ-56' FROM Table_1
WHERE Table_1.GROUP_ID = 'com.abc' AND Table_1.ARTIFACT_ID = 'pqrd' AND
Table_1.VERSION = '4.0.0'
正如您从上述查询中推断的那样,我首先尝试从 TABLE_1 中获取给定 GROUP_ID
、ARTIFACT_ID
和 VERSION
值的 ID
,然后使用检索到的 @987654329 将数据插入 TABLE_2 @ 和 ISSUE_KEY
的值为 XYZ-56
。
执行上述命令后,Table_2 将如下所示
ID, MODULE_ID, ISSUE_KEY
11, 104, XYZ-12
12, 104, XYZ-34
13, 104, XYZ-56
上述INSERT
查询的问题是它不会检查是否已经存在具有特定值MODULE_ID
和ISSUE_KEY
的给定行。例如,如果我再次执行相同的插入查询,那么表将如下所示
ID, MODULE_ID, ISSUE_KEY
11, 104, XYZ-12
12, 104, XYZ-34
13, 104, XYZ-56
14, 104, XYZ-56
我希望仅将行插入到 Table_2 中,因为给定的 MODULE_ID
和 ISSUE_KEY
已经不存在任何行。
有人可以帮我修改上面的插入查询以按预期进行。
【问题讨论】:
使用不存在像这里***.com/a/41186684/2562699 【参考方案1】:您可以使用WHERE NOT EXISTS
:
Insert Into Table_2 (MODULE_ID, ISSUE_KEY)
Select ID, 'XYZ-56'
From Table_1 T1
Where T1.GROUP_ID = 'com.abc'
And T1.ARTIFACT_ID = 'pqrd'
And T1.VERSION = '4.0.0'
And Not Exists
(
Select *
From Table_2 T2
Where T2.Module_Id = T1.Id
And T2.Issue_Key = 'XYZ-56'
);
这是使用CTE
和LEFT JOIN
的另一种方法:
;With ToInsert As
(
Select ID As Module_Id, 'XYZ-56' As Issue_Key
From Table_1 T1
Where T1.GROUP_ID = 'com.abc'
And T1.ARTIFACT_ID = 'pqrd'
And T1.VERSION = '4.0.0'
)
Insert Table_2
(Module_Id, Issue_Key)
Select I.Module_Id, I.Issue_Key
From ToInsert I
Left Join Table_2 T2 On T2.Module_Id = I.Module_Id
And T2.Issue_Key = I.Issue_Key
Where T2.Id Is Null;
【讨论】:
【参考方案2】:您可以使用下面的 if 块来检查记录是否存在:
IF NOT EXISTS (SELECT * FROM Table_2 WHERE ISSUE_KEY = 'XYZ-56')
BEGIN
INSERT INTO Table_2 (MODULE_ID, ISSUE_KEY) SELECT ID, 'XYZ-56' FROM Table_1
WHERE Table_1.GROUP_ID = 'com.abc' AND Table_1.ARTIFACT_ID = 'pqrd' AND
Table_1.VERSION = '4.0.0'
END
【讨论】:
【参考方案3】:你可以使用except
:
INSERT INTO Table_2 (MODULE_ID, ISSUE_KEY)
SELECT ID, 'XYZ-56'
FROM Table_1
WHERE Table_1.GROUP_ID = 'com.abc'
AND Table_1.ARTIFACT_ID = 'pqrd'
AND Table_1.VERSION = '4.0.0'
except
select MODULE_ID, ISSUE_KEY
from Table_2
或not exists()
:
INSERT INTO Table_2 (MODULE_ID, ISSUE_KEY)
SELECT ID, 'XYZ-56'
FROM Table_1
WHERE Table_1.GROUP_ID = 'com.abc'
AND Table_1.ARTIFACT_ID = 'pqrd'
AND Table_1.VERSION = '4.0.0'
and not exists (
select 1
from table_2 as i
where i.Module_ID = table_1.ID
and i.Issue_Key = 'XYZ-56'
)
或其他类似方法。
【讨论】:
虽然它可能是可取的,但使用except
也可以删除重复项。这也表明它进行了额外的、不必要的处理。
@GordonLinoff 是的,它确实删除了重复项。在检查相等性时,它还会以不同的方式处理 null
值。【参考方案4】:
您正在寻找Merge 声明。
引用文档:
根据与源表连接的结果对目标表执行插入、更新或删除操作。例如,您可以通过根据在另一个表中发现的差异在一个表中插入、更新或删除行来同步两个表。
注意:仔细阅读性能提示。
【讨论】:
以上是关于仅当行不存在时才插入 SQL的主要内容,如果未能解决你的问题,请参考以下文章
仅当行不存在时,如何将一行添加到不同子目录下的多个文本文件?