我有以下两张表:

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

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

我需要插入从Table1Table2的数据.我可以使用以下语法:

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语句.

推荐答案

使用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

在这三种 Select 中,LEFT JOIN/IS NULL的效率较低.见this link for more details.

Sql相关问答推荐

无效和不匹配的计数

在SQL中创建一个计数器,根据BigQuery/SQL中的条件递归地添加行值

在甲骨文中查找前一个星期一的S日期

使用WHERE子句进行筛选时,SQL SELECT查询返回总计数

更新其组的日期字段值小于最大日期减go 天数的记录

值对于类型字符来说太长

找到最新的连线

如何从Spark SQL的JSON列中提取动态数量的键值对

用于从第二个表中提取具有最小最终价格值的记录的SQL查询

明细表中没有记录如何更新主表的值为0

SQL中相同表内的VLOOKUP等价

删除行而不使数据库超载

如何根据 SQL 中的阈值标记一个集群中的所有值?

DB2 SQL查询结果多余数据

在 PostgreSQL 中,如何让多个判断约束引用相同的值数组?

如何使用最后一个非 NULL 值在 PostgreSQL 列中填充 NULL 值

我们可以使用连接改进包含多个子查询的查询吗

PostgreSQL - 递归地聚合来自不同列的属性

使用 PL/PGSQL 函数 Select 返回多条记录

PlSql 陷入死循环