ON DUPLICATE KEY连接*列的每个值

问题描述

这是一个令人头疼的事情。

我在CONCAT的上下文中使用ON DUPLICATE KEY UPDATE,它吐出了非常奇怪的结果。

假设一个表存在两列三行,因此:

term   | reference
0cm    | 49-5;
10p    | 890-1;
11s    | 491-1;
16761  | 768-1;

(尽管有数字,但它们都是VARCHAR字符串。)

现在假设我们运行以下查询

INSERT INTO dictionary (`term`,`references`) 
VALUES 
('0cm','35-6;'),('10p','89-12;'),('16761','491-7;') 
ON DUPLICATE KEY UPDATE 
`references` = CONCAT(`references`,`references` = CONCAT(`references`,'491-7;');

因为term是唯一索引,所以ON DUPLICATE KEY成为脚本的活动部分(保留不受影响的11s)。预期的行为是我们的新值将被追加到现有值。

查询成功运行,但是给了我这些意外的结果:

term   | reference
0cm    | 49-5;35-6;89-12;491-7;
10p    | 890-1;35-6;89-12;491-7;
11s    | 491-1;
16761  | 768-1;35-6;89-12;491-7;

它已将{em> 的每个值reference连接起来。

reference执行其ON DUPLICATE KEY之前,有什么方法可以“清除” UPDATE引用吗?

解决方法

INSERT INTO dictionary (`term`,`references`) 
VALUES 
('0cm','35-6;'),('10p','89-12;'),('16761','491-7;') 
ON DUPLICATE KEY UPDATE 
`references` = CASE term WHEN '0cm'   THEN CONCAT(`references`,'35-6;')
                         WHEN '10p'   THEN CONCAT(`references`,'89-12;')
                         WHEN '16761' THEN CONCAT(`references`,'491-7;')
                         END;

或者简单地

INSERT INTO dictionary (`term`,'491-7;') 
ON DUPLICATE KEY UPDATE 
`references` = CONCAT(`references`,VALUES(references));
,

如果没有重复键,请使用VALUES(references)获取将要插入到该行中的值。

INSERT INTO dictionary (`term`,VALUES(`references`));

顺便说一句,您应该阅读以下内容:Is storing a delimited list in a database column really that bad?

,

我怀疑您想要

INSERT INTO dictionary (term,references)
VALUES 
('0cm','491-7;') 
ON DUPLICATE KEY UPDATE 
    references = CONCAT_WS(';',references,VALUES(reference));

当给出重复的reference时,此字段将附加到term列中。请注意,concat_ws()可以正确处理références最初为null的边缘情况。