ON DUPLICATE KEY 连接列的*每个*值

ON DUPLICATE KEY concatenates *every* value of column

这是一个令人头疼的问题。

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

假设table存在两列三行,因此:

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`,'35-6;'),
`references` = CONCAT(`references`,'89-12;'),
`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;

它连接了 reference 的每个 值。

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

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`,`references`) 
VALUES 
('0cm','35-6;'),
('10p','89-12;'),
('16761','491-7;') 
ON DUPLICATE KEY UPDATE 
`references` = CONCAT(`references`, VALUES(references));

我怀疑你想要:

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

当给出重复的 term 时,这将附加到列 reference。请注意 concat_ws() 正确处理 références 最初是 null.

的边缘情况

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

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

顺便说一句,你应该阅读这个:Is storing a delimited list in a database column really that bad?