sql在重复密钥更新时插入多条记录

amrnrhlw  于 2021-06-23  发布在  Mysql
关注(0)|答案(3)|浏览(362)

我有一个查询,作为一个查询一次性插入多个数据。

INSERT INTO tableName (COLUMN_1, COLUMN_2, COLUMN_3) 
SELECT 'test1', 'test2', 'test3'
UNION ALL
SELECT 'test4', 'test5', 'test6'
UNION ALL
SELECT 'test7', 'test8', 'test8'

使用上面的代码,有没有一种方法来实现“复制密钥更新”?比如:

INSERT INTO tableName (COLUMN_1, COLUMN_2, COLUMN_3)
SELECT 'test1', 'test2', 'test3'
ON DUPLICATE KEY UPDATE COLUMN_1='new', COLUMN_2='new', COLUMN_3='new'
UNION ALL
SELECT 'test1', 'test2', 'test3'
ON DUPLICATE KEY UPDATE COLUMN_1='new', COLUMN_2='new', COLUMN_3='new'
UNION ALL
SELECT 'test1', 'test2', 'test3'
ON DUPLICATE KEY UPDATE COLUMN_1='new', COLUMN_2='new', COLUMN_3='new';

注意:这可能无关紧要或毫无意义,但我是用mysql workbench完成的。

kgqe7b3p

kgqe7b3p1#

你可以这样做:

INSERT INTO tableName (COLUMN_1, COLUMN_2, COLUMN_3)
SELECT * FROM (
    SELECT 'test1', 'test2', 'test3'
    UNION ALL
    SELECT 'test4', 'test5', 'test6'
    UNION ALL
    SELECT 'test7', 'test8', 'test8') AS derived_table
ON DUPLICATE KEY UPDATE COLUMN_1='new', COLUMN_2='new', COLUMN_3='new'

说明:
你得把这些东西分开 SELECT 以及insert语句。i、 e.一 INSERT 只能有一个 SELECT . 那你就可以了 UNION -在select中。
如相关手册页所述, INSERT INTO ... SELECT ... UNION 不支持 ON DUPLICATE KEY UPDATE -s。但是,它们在派生表(又称子查询)上支持它。

jjjwad0x

jjjwad0x2#

你的查询基本上是正确的,只要去掉中间的 ON DUPLICATE KEY... . 不需要派生表,因为您没有从联合引用列。

INSERT INTO tableName (COLUMN_1, COLUMN_2, COLUMN_3) 
SELECT 'test8', 'test9', 'test10'
UNION ALL
SELECT 'test4', 'test5', 'test6'
UNION ALL
SELECT 'test9', 'test5', 'test6'
ON DUPLICATE KEY UPDATE COLUMN_1='new', COLUMN_2='new', COLUMN_3='new';

您将遇到的问题是,如果您在 INSERT . 在这种情况下 UPDATE 将尝试将两行设置为具有相同的键(“new”)和 INSERT 会失败的。您可以通过更改查询来解决这个问题,以便 UPDATE 包括部分旧列值。在这种情况下,由于要引用列值,因此需要一个派生表:

INSERT INTO tableName (COLUMN_1, COLUMN_2, COLUMN_3) 
SELECT * FROM (
    SELECT 'test8', 'test9', 'test10'
    UNION ALL
    SELECT 'test4', 'test5', 'test6'
    UNION ALL
    SELECT 'test1', 'test5', 'test6') AS dt
ON DUPLICATE KEY UPDATE COLUMN_1=CONCAT('new', COLUMN_1), COLUMN_2='new', COLUMN_3='new';

更新的sqlfiddle

km0tfn4u

km0tfn4u3#

您还没有指定您拥有的主键和唯一索引,但是这将起作用-文档中提到了这种情况。根据找到行时的唯一约束,将更新所有三列值(即使它们不是唯一键的一部分)。

INSERT INTO tableName (COLUMN_1, COLUMN_2, COLUMN_3)
SELECT *
FROM (
  SELECT 'test1', 'test2', 'test3'
  UNION ALL
  SELECT 'test4', 'test5', 'test6'
  UNION ALL
  SELECT 'test7', 'test8', 'test8'
) AS dt
ON DUPLICATE KEY UPDATE
    COLUMN_1 = 'new'
  , COLUMN_2 = 'new'
  , COLUMN_3 = 'new'

为了测试这一点,最好包含一些额外的行,因为示例数据中的每个值都是唯一的,并且您无法观察其行为。

相关问题