从表2更新表1(插入新的、仅更新更改的、删除丢失的)

x3naxklr  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(419)

我看到类似的问题问了十几次,但没有一次完全符合我的设想。
我的目的是根据csv导入的临时表(表2)更新当前表(表1);
删除缺少的 appid s
添加新的 appid s
更新 name 如果它改变了
另外,更新后还有两个触发器(由于它,我意识到我在做什么,而不是简单地用坏代码运行);
历史记录表中的日志更新(表3)
历史记录表中的日志删除(表3)
目前我执行的操作如下:

CREATE TEMPORARY TABLE table2 (
    appid INT,
    name VARCHAR(255)
    );
LOAD DATA LOCAL INFILE "outp.csv" INTO TABLE table2 
    FIELDS TERMINATED BY ','
    ENCLOSED BY '"'
    LINES TERMINATED BY '\n';

UPDATE table1
INNER JOIN table2 ON table2.appid = table1.appid
SET table1.name = table2.name;

DROP TEMPORARY TABLE table2;

当前,每当我运行更新时,history表都会获取所有现有行,并且不会导入新行,也不会删除缺少的行。
完成预期更新操作的正确方法是什么?
编辑:事实上,使用下面gmb提供的确切声明更有意义。在我了解了insert语句的工作原理之后,避免运行第三条不必要的语句就更有意义了,因为insert将在一条语句中执行insert和update。
旧的三句话脚本供参考:

DELETE FROM table1
WHERE NOT EXISTS(
    SELECT 1
    FROM table2
    WHERE table2.appid = table1.appid
    );

UPDATE table1 INNER JOIN table2 ON table2.appid = table1.appid
SET table1.name = table2.name
WHERE table1.name <> table2.name;

INSERT INTO table1 (appid, name)(
    SELECT table2.appid, table2.name FROM table2
    LEFT JOIN table1 ON table2.appid = table1.appid
    WHERE table1.appid IS NULL
    );
vm0i2vca

vm0i2vca1#

你不能一句话就说出来。与其他一些数据库不同,mysql/mariadb没有提供功能齐全的 merge 声明。
但是,您可以分两步执行操作:首先清除目标中“丢失”的行,然后使用 insert ... on duplicate key 要插入/更新新行和现有行,请执行以下操作:

delete from table1 
where not exists(select 1 from table2 where table2.appid = table1.appid)

insert into table1 (appid, name)
select appid, name
from table2
on duplicate key update name = values(name)

当然,这是假设 id 是的主键 table1 (因此 insert 语句可以正确识别重复项)。我还建议定义 id 作为临时表的主键 table2 :这将使查询更快。

相关问题