我有一个包含以下架构的MySQL表
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(7) | NO | UNI | NULL | auto_increment |
| title | varchar(20) | NO | PRI | NULL | |
+-------+-------------+------+-----+---------+----------------+
以下是其中的内容。
+----+-------+
| id | title |
+----+-------+
| 1 | a |
| 2 | b |
+----+-------+
问题:我想在单个查询中交换值,以便表现在变为
+----+-------+
| id | title |
+----+-------+
| 1 | b |
| 2 | a |
+----+-------+
我试过了:UPDATE myTable SET title = CASE id WHEN 1 THEN "b" WHEN 2 THEN "a" END;
但它给我一个错误ERROR 1062 (23000): Duplicate entry 'b' for key 'PRIMARY'
我该怎么办?
在其中一个链接中找到的解决方案似乎是现在的唯一方法,但我仍在寻找更好的解决方案
START TRANSACTION;
UPDATE prime SET title = CASE id WHEN 1 THEN "$b" WHEN 2 THEN "$a" END;
UPDATE prime SET title = CASE id WHEN 1 THEN SUBSTRING(title,2) WHEN 2 THEN SUBSTRING(title,2) END;
COMMIT;
答案 0 :(得分:1)
START TRANSACTION ;
UPDATE prime SET title = 'zzzzz$$$$$xxxxx!@#$%' WHERE id = 1 ;
UPDATE prime SET title = 'a' WHERE id = 2 ;
UPDATE prime SET title = 'b' WHERE id = 1 ;
COMMIT ;
评论,与独特问题无关:
在更新语句中使用WHERE
,除非您要更新表的所有行。你的陈述:
UPDATE myTable SET title = CASE id WHEN 1 THEN 'b' WHEN 2 THEN 'a' END;
(如果有效)它还会尝试使用id >= 3
值更新所有其他行(NULL
),因为CASE
具有隐式ELSE NULL
部分。当然它会失败,因为title
是主键,但在其他情况下,你会产生不良影响。
答案 1 :(得分:0)
使用PIMARY密钥帮助使用ORDER BY title
UPDATE myTable SET title = CASE id WHEN 1 THEN "a" WHEN 2 THEN "b" ElSE title END WHERE id in (1,2) ORDER BY id DESC;
如果不工作,则改变ASC或ORDER BY标题的方向。并且不要模仿ELSE。它不起作用。
我将它与id一起使用,就像那样:
UPDATE `table1` SET `id` = CASE `id` WHEN 1 THEN 2 WHEN 2 THEN 3 WHEN 0 THEN 1 ELSE `id` END WHERE `id` IN ( 1, 2, 0 ) ORDER BY `id` DESC
一切正常, 但是如果更新0 => 3,3 => 2,2 => 1 - 0应该分开更新。