SQL在使用ON DUPLICATE KEY UPDATE时插入多个记录

时间:2018-08-07 07:22:33

标签: mysql sql sql-insert

我有一个查询,可以一次查询多个数据。

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'

使用上面的代码,有没有办法实现“ ON DUPLICATE KEY UPDATE”? 像这样:

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工作台进行此操作。

3 个答案:

答案 0 :(得分:2)

您可以这样做:

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语句分开。即一个INSERT只能有一个SELECT。然后,您可以在选择范围内执行UNION-。
  • related manual page所述,INSERT INTO ... SELECT ... UNION不支持ON DUPLICATE KEY UPDATE -s。但是,他们在派生表(又名子查询)上支持它。

答案 1 :(得分:2)

您尚未指定主键和唯一索引,但是仍然可以使用-documentation提到了这种情况。根据找到行的唯一约束,所有三个列的值都会更新(即使它们不是唯一键的一部分)。

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'

要对此进行测试,最好再添加一些行,因为示例数据中的每个值都是唯一的,并且您无法观察到行为。

答案 2 :(得分:2)

您的查询基本上是正确的,只是摆脱了中间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将尝试将两行设置为具有相同的键(“新”),而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';

Updated SQLFiddle