我知道ON DUPLICATE KEY UPDATE
如果已经有该键的记录,您可以使用它来更新某个值,
我可以做这个:
INSERT INTO `tableName` (`a`,`b`,`c`) VALUES (1, 2, 3)
ON DUPLICATE KEY UPDATE `a`=1, `b`=2, `c`=3
但是我怎样才能做到这一点而不必写出两次列和值呢?
我知道ON DUPLICATE KEY UPDATE
如果已经有该键的记录,您可以使用它来更新某个值,
我可以做这个:
INSERT INTO `tableName` (`a`,`b`,`c`) VALUES (1, 2, 3)
ON DUPLICATE KEY UPDATE `a`=1, `b`=2, `c`=3
但是我怎样才能做到这一点而不必写出两次列和值呢?
您无需重复该值即可达到一半:
INSERT INTO `tableName` (`a`,`b`,`c`) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE `a`=VALUES(`a`), `b`=VALUES(`b`), `c`=VALUES(`c`);
但是您仍然必须列出列。
如果有用,我进行了查询以避免手动编写“重复”查询的最后一部分,对于版本> = 5.0:
SELECT GROUP_CONCAT( CONCAT(COLUMN_NAME,"=values(", COLUMN_NAME,")") SEPARATOR ", ") FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'database_name' AND TABLE_NAME = 'table_name';
它的输出是这样的:
a=values(a), b=values(b), c=values(c), d=values(d)
在具有列 a、b、c 和 d 的表上,因此您可以附加到查询的第一部分:
INSERT INTO `tableName` (`a`,`b`,`c`, `d`) VALUES (1,2,3,4) ON DUPLICATE KEY UPDATE a=values(a), b=values(b), c=values(c), d=values(d)
更新: 对于很长的列列表,您可能会看到截断的输出,您可以在上面的查询之前使用此语句(感谢Uncle iroh):
SET SESSION group_concat_max_len = 1000000;
根据 @BhendiGawaar 在 Orbit 的回答中对 @Lightness Races 的评论,这里是 MySQL 8.019+ 版本:
INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new
ON DUPLICATE KEY UPDATE c = new.a+new.b;
或者
INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new(m,n,p)
ON DUPLICATE KEY UPDATE c = m+n;
也适用于set
:
INSERT INTO t1 SET a=1,b=2,c=3 AS new
ON DUPLICATE KEY UPDATE c = new.a+new.b;
INSERT INTO t1 SET a=1,b=2,c=3 AS new(m,n,p)
ON DUPLICATE KEY UPDATE c = m+n;
关于使用的弃用警告VALUES
:
从 MySQL 8.0.20 开始不推荐使用 VALUES() 来引用新的行和列,并且在未来的 MySQL 版本中可能会被删除。相反,请使用行和列别名,如本节接下来的几段所述。
我知道这是一个老问题,这是一个有点不合常规的答案,但是我遇到了同样的事情,并且在设置另一个答案中提到的 group_concat_max_len 属性时遇到了问题,并且总是得到一个截断的结果。在编写长脚本时,我最终选择的另一个选择是在 excel 中使用这个公式:
=SUBSTITUTE(TRIM(A1), ",", "") & " = VALUES(" & SUBSTITUTE(TRIM(A1), ",", "") & "),"
其中 A1 是您将字段名称复制到的单元格。要快速做到这一点,我会右键单击表格并将 select 语句复制到剪贴板,它会为您提供所有列名称,公式会删除逗号。
希望这对某人有帮助!