您可以尝试使用TRIGGER
.
CREATE TRIGGER check_unique BEFORE UPDATE ON `images`
FOR EACH ROW
SET NEW.isMain = IF(NEW.isMain = 0, 0,
CASE WHEN ( SELECT MAX(isMain) FROM images AS q WHERE q.prod = NEW.prod ) = 1
THEN NULL ELSE NEW.isMain END);
或者,更快(尤其是索引时)
CREATE TRIGGER check_unique BEFORE UPDATE ON `images`
FOR EACH ROW
SET NEW.isMain = IF(NEW.isMain = 0, 0,
IF (EXISTS ( SELECT * FROM images AS q WHERE q.prod = NEW.prod AND q.isMain = 1), NULL, 1));
这将允许将 isMain 始终设置为 0;如果要将其设置为 1,那么它将检查同一产品是否没有其他行的 isMain 为 1。
例子
在下面的示例中,我无法设置isMain = 1
位置,prod=3
直到我设置isMain=0
了具有isMain = 1
.
CREATE TABLE images (
image_id integer not null primary key auto_increment,
prod integer not null, isMain integer not null );
INSERT INTO images VALUES (1, 1, 0), (2, 1, 1), (3, 2, 0), (4, 2, 1);
select * from images;
+----------+------+--------+
| image_id | prod | isMain |
+----------+------+--------+
| 1 | 1 | 0 |
| 2 | 1 | 1 |
| 3 | 2 | 0 |
| 4 | 2 | 1 |
+----------+------+--------+
CREATE TRIGGER check_unique BEFORE UPDATE
ON `images` FOR EACH ROW
SET NEW.isMain = IF(NEW.isMain = 0, 0, IF (EXISTS ( SELECT * FROM images AS q WHERE q.prod = NEW.prod AND q.isMain = 1), NULL, 1));
UPDATE images SET isMain = 1 WHERE image_id = 3;
ERROR 1048 (23000): Column 'isMain' cannot be null
UPDATE images SET isMain = 0 WHERE image_id = 4;
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 1
UPDATE images SET isMain = 1 WHERE image_id = 3;
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 1
您可以扩展此方法,以便您始终可以将任何行的 isMain 设置为 1 ...但该产品之前为 isMain 的行被归零。