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?
这是一个令人头疼的问题。
我在 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?