使用 Oracle SQL 从一个表插入到另一个表时如何避免重复行?

Posted

技术标签:

【中文标题】使用 Oracle SQL 从一个表插入到另一个表时如何避免重复行?【英文标题】:How to avoid duplicate rows when inserting from one table to another with Oracle SQL? 【发布时间】:2020-10-02 09:52:13 【问题描述】:

我有两张表,结构如下:

TABLE_A

id_a|name_a|identifier_a
1   |toto  |uuuu
2   |titi  |oooo
3   |tutu  |vvvv  

TABLE_B

id_b|name_b|identifier_b
1   |toto  |uuuu
11  |tyty  |tttt
56  |tetu  |bbbb  

我正在尝试通过使用标识符列将数据从 TABLE_B 插入到 TABLE_B 而不重复行。所以,预期的结果应该是:

id_a|name_a|identifier_a
1   |toto  |uuuu
2   |titi  |oooo
3   |tutu  |vvvv
11  |tyty  |tttt
56  |tetu  |bbbb

执行此操作的以下请求是:

INSERT INTO TABLE_A(ID_A, NAME_A, IDENTIFIER_A)
SELECT ID_B, NAME_B, IDENTIFIER_B 
FROM TABLE_B
WHERE NOT EXISTS (SELECT IDENTIFIER_A FROM TABLE_A);

但我收到一条错误消息,指出某列无效 (???):

SQL Error : ORA-00904: "IDENTIFIER_B" : 00904. 00000 -  "%s: invalid identifier"

你有更好的想法来做这个插入吗?

【问题讨论】:

【参考方案1】:

您可以为此目的使用MERGE 语句 - 仅插入目标表中不存在的行。

检查documentation - MERGE 语句也可以更新现有行

MERGE INTO TABLE_B b
USING TABLE_A a
ON (a.id_a = b.id_b)
WHEN NOT MATCHED THEN INSERT (id_b, name_b, identifier_b)
  VALUES (id_a, name_a, identifier_a)

【讨论】:

【参考方案2】:

错误信息很清楚:表b 中没有名为identifier_b 的列。您需要使用正确的列名。

不过,让我指出,您的查询没有做您想做的事情:您需要关联 EXISTS 子查询,否则永远不会插入任何行(除非 table_a 开始时为空)。

我认为你想要的逻辑是:

insert into table_a(id_a, name_a, identifier_a)
select id_b, name_b, identifier_b 
from table_b b
where not exists (select 1 from table_a a where a.identifier_a = b.identifier_b);

【讨论】:

以上是关于使用 Oracle SQL 从一个表插入到另一个表时如何避免重复行?的主要内容,如果未能解决你的问题,请参考以下文章

从一个表中选择,插入另一个表 oracle sql 查询

oracle中如何将数据从一个表复制到另一个表(仅复制其中某些字段)

SQL 将某些数据从一个表插入到另一个表

带有 pg8000 的 PostgreSQL - 从 SQL 插入结果到另一个表

Oracle中把一张表查询结果插入到另一张表中

sql语句 怎么从一张表中查询数据插入到另一张表中