如果我有一个包含2列的表,那么如果我要更新该表中创建重复行的列,那么这个表也有唯一约束,如果我在创建唯一行时有任何方法更新我可以处理那一行吗?
答案 0 :(得分:0)
通常添加带有一些条件和可选处理的SQL内联IF语句以及用于检测重复的自联接将执行您正在寻找的内容。真正的答案将特定于您的结构,但我将举例说明一个名为user
的表,其中一个名为id
的列是主键,SSN
具有唯一约束在上面。我们将用2个用户填充它并更新其中一个以复制唯一ssn列中的第一个“
CREATE TABLE `test`.`user` (
`id` INT NOT NULL,
`SSN` VARCHAR(45) NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `ssn_UNIQUE` (`SSN` ASC));
INSERT INTO user VALUES (1, "1234567"), (2, "0123456");
正如您所注意到的,如果我在另一个用户(其中id = 1)已经拥有SSN =“1234567”时运行以下更新,那么我们将不会进行任何更新。
UPDATE user SET SSN="1234567" WHERE id=2;
ERROR 1062 (23000): Duplicate entry '1234567' for key 'ssn_UNIQUE'
但是,请考虑以下内容:
UPDATE user u
LEFT JOIN user AS u2
ON u2.SSN="1234567"
SET u.SSN=IF(
u2.id IS NOT NULL,
CONCAT(u2.SSN, "duplicates", u2.id, "onto", u.id),
"1234567")
WHERE u.id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
在上面的示例中,可能会出现以下情况:
如果用户ID = 1已经有SSN =“1234567”,并且我运行了上述更新,结果将是:
SELECT * FROM test.user;
+----+--------------------------+
| id | SSN |
+----+--------------------------+
| 2 | 1234567duplicates1onto2 |
| 1 | 1234567 |
+----+--------------------------+
2 rows in set (0.00 sec)
如果我尝试改为设置为“01234567”,并且我运行相同的上述更新,结果将是:
SELECT * FROM test.user;
+----+----------+
| id | SSN |
+----+----------+
| 2 | 01234567 |
| 1 | 1234567 |
+----+----------+
2 rows in set (0.00 sec)
如果我有第三个用户,如果另外两个用户尝试将值设置为“1234567”,则该用户可能具有值“1234567duplicates2”:
SELECT * FROM test.user;
+----+-------------------------+
| id | SSN |
+----+-------------------------+
| 1 | 1234567 |
| 2 | 1234567duplicates1onto2 |
| 3 | 1234567duplicates1onto3 |
+----+-------------------------+
3 rows in set (0.00 sec)
如您所见,“在”部分允许我在同一更新批次中包含许多重复项。
要调整此技术,只需将内联IF的输出更改为您将用于处理的公式,并且JOIN的条件应该是提供重复检测的任何内容。
http://dev.mysql.com/doc/refman/5.1/en/control-flow-functions.html