使用单独的更新列插入重复密钥更新批处理

时间:2018-03-24 19:16:11

标签: mysql sql insert query-optimization batch-query

我有一种情况,我有一个表(col1 (pk), col2, col3, col4)和一组记录,我需要将其插入表中,并在重复键上更新它们。我想做一个批量查询来加快速度。但是,col4没有NOT NULL约束。当我想要使用记录(val1, val2, val3, None), (val4, val5, val6, val7)进行更新时,会出现问题。对于第一条记录,我不希望更新第4列(如果在DB中存在(val1, val2, val3, val8)我不想覆盖val8,因为None表示缺少值而不是显式设置为空值)。但是,对于第二条记录,我希望更新col4,因为传递了显式值。对于一条记录,我只想将更新列设置为col2, col3,而不是col4,这样就可以了,但我想批量处理此查询,并且需要在{a}}时更新col4价值是为它传递的,当我没有价值时不会更新。我逻辑上需要下面给出的东西。

INSERT INTO table1
  (col1, col2, col3, col4)
VALUES
  ('val1', 'val2', 'val3'), ON DUP KEY UPDATE col2, col3
  ('val5', 'val6', 'val7', 'val8'), ON DUP KEY UPDATE col2, col3, col4
  ('val9', 'val10', 'val11') ON DUP KEY UPDATE col2, col3

显然,这可以通过将其作为一系列单独的语句来完成,但我想找到一种批处理方法。有没有办法在sql中完成这个或不同的方法?

3 个答案:

答案 0 :(得分:1)

VALUES中的字段数必须与INSERT中的字段数相同。但是你可以只为NULL传递col4并在UPDATE部分中使用COALESCE。

INSERT INTO table1
  (col1, col2, col3, col4)
VALUES
  ('val1', 'val2',  'val3',  NULL),
  ('val5', 'val6',  'val7',  'val8'),
  ('val9', 'val10', 'val11', NULL)
ON DUPLICATE KEY UPDATE
  col2 = VALUES(col2),
  col3 = VALUES(col3),
  col4 = COALESCE(VALUES(col4), col4)

答案 1 :(得分:1)

这是你要找的东西吗?

INSERT INTO table1
  (col1, col2, col3, col4)
VALUES
  ('val1', 'val2', 'val3', null)
  ('val5', 'val6', 'val7', 'val8')
  ('val9', 'val10', 'val11', null)
ON DUPLICATE KEY UPDATE
  col2 = values(col2),
  col3 = values(col3),
  col4 = coalesce(values(col4), col4)
;

答案 2 :(得分:1)

在插入的on duplicate key update部分中,您可以使用values来引用插入的值。在coalesce

的情况下,您可以使用null来保留更新前的值
INSERT INTO YourTable (col1, col2, col3, col4) VALUES
    ('val1', 'val2', 'val3', null)
,   ('val5', 'val6', 'val7', 'val8')
,   ('val9', 'val10', 'val11', null)
ON DUPLICATE KEY UPDATE
    col1 = values(col1)
,   col2 = values(col2)
,   col3 = values(col3)
,   col4 = coalesce(values(col4), col4)

Example on SQL Fiddle.

在回复您的评论时,您可以使用null明确设置case

,   col4 = case values(col4) 
           when 'None' then null 
           else coalesce(values(col4), col4)
           end

此处存在的明显风险是您无法再更新为无:)