我有一个名为“ images”的表,其中包含几行图像名称和位置值(它们在网站上显示的顺序)。
id name position
1 dog.png 3
2 cat.png 1
3 snake.png 2
我想做的是,如果所有位置列值都超过特定值,则将它们递减。
例如,如果要删除“ cat”,我想查找位置更高的所有行(将是蛇和狗)并将其位置值减1。我需要
的SQL语句“更新“位置”>“值”的所有“位置”列”
我知道我需要获取要删除的图像的“位置”,并将其设置为“值”,然后再更新具有较高位置列的其余行。但是,我不确定如何为其余部分创建SQL语句。
“更新“位置”>“值”的所有“位置”列”
我不确定是否需要一两个查询。
答案 0 :(得分:3)
您可以使用以下简单的UPDATE
:
UPDATE images SET position = position - 1 WHERE position > 1
您还可以使用以下内容来UPDATE
图像和DELETE
特定图像:
-- first update the other images
UPDATE images t1, (SELECT * FROM images WHERE id = 2) t2 SET t1.position = t1.position - 1 WHERE t1.position > t2.position
-- now you can delete the image
DELETE FROM images WHERE id = 2
受Tim Biegeleisen's solution的启发,您可以在删除一个或多个图像后使用以下UPDATE
来缩小间隔。在这种情况下,您必须使用MySQL 8.0或更高版本(用于ROW_NUMBER
):
UPDATE images t1,
(SELECT id, ROW_NUMBER() OVER (ORDER BY position) rn FROM images) t2
SET t1.position = t2.rn
WHERE t1.id = t2.id
在这种情况下,您还可以像这样删除多个图像:
DELETE FROM images WHERE id IN (1, 2)
答案 1 :(得分:2)
实际上,我建议删除记录后再次建议 进行更新。相反,只需使用ROW_NUMBER
来生成每条记录的有效位置,例如
SELECT
id,
name,
ROW_NUMBER() OVER (ORDER BY position) position
FROM yourTable;
删除行不会更改表中所有记录之间存在的相对顺序。
如果您未使用MySQL 8+,则可以轻松地使用用户变量模拟行号。
答案 2 :(得分:0)
我将使用触发器:
DELIMITER //
CREATE TRIGGER position_after_delete
AFTER DELETE
ON images FOR EACH ROW
BEGIN
-- Update position
UPDATE images SET position = position - 1 WHERE position > OLD.position
END; //
DELIMITER ;