MySQL正确的语句为“更新所有行,其中列>编号”?

时间:2019-05-31 08:54:19

标签: mysql

我有一个名为“ images”的表,其中包含几行图像名称和位置值(它们在网站上显示的顺序)。

id      name       position
1       dog.png    3
2       cat.png    1
3       snake.png  2

我想做的是,如果所有位置列值都超过特定值,则将它们递减。

例如,如果要删除“ cat”,我想查找位置更高的所有行(将是蛇和狗)并将其位置值减1。我需要

的SQL语句

“更新“位置”>“值”的所有“位置”列”

我知道我需要获取要删除的图像的“位置”,并将其设置为“值”,然后再更新具有较高位置列的其余行。但是,我不确定如何为其余部分创建SQL语句。

“更新“位置”>“值”的所有“位置”列”

我不确定是否需要一两个查询。

3 个答案:

答案 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

demo on dbfiddle.uk

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)

demo on dbfiddle.uk

答案 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 ;