如果我有下表&数据允许我们使用sort_index
进行排序:
CREATE TABLE `foo` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`bar_id` INT(11) DEFAULT NULL,
`sort_index` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `foo` (`bar_id`, `sort_index`) VALUES
(1,1),(1,2),(1,3),(1,4),
(2,1),(2,2),(2,3),(2,4),(2,5);
我希望能够以最有效的方式执行以下操作:
sort_index
始终为1个索引并且没有间隙 UPDATE
上循环它们并不理想)为了澄清我正在尝试做的事情,让我们假设该表是空的,所以我们有以下数据:
id | bar_id | sort_index
1 | 1 | 1
2 | 1 | 2
3 | 1 | 3
4 | 1 | 4
5 | 2 | 1
6 | 2 | 2
7 | 2 | 3
8 | 2 | 4
9 | 2 | 5
然后,如果我们要做以下的动作
我们应该得到以下数据:
id | bar_id | sort_index
1 | 1 | 3
2 | 1 | 1
3 | 1 | 2
4 | 1 | 4
5 | 2 | 5
6 | 2 | 2
7 | 2 | 1
8 | 2 | 3
9 | 2 | 4
SELECT * FROM foo ORDER BY bar_id, sort_index;
给了我们:
id | bar_id | sort_index
2 | 1 | 1
3 | 1 | 2
1 | 1 | 3
4 | 1 | 4
7 | 2 | 1
6 | 2 | 2
8 | 2 | 3
9 | 2 | 4
5 | 2 | 5
答案 0 :(得分:3)
您应该可以在一个查询中执行此操作:UPDATE foo SET sort_index = sort_index + 1 WHERE bar_id == b AND sort_index < s1 AND sort_index >= s2
行,其中b
是要移动的行的bar_id
,{{1} }是该行的当前s1
,而sort_index
是您要将其移至的s2
。然后,您只需更改行的sort_index
。
您可能希望在事务中执行两个查询。此外,如果您使用sort_index
之类的内容在sort_index
上创建索引,则可能会加快速度。
(顺便说一下,在这里我假设您不希望在给定的CREATE INDEX foo_index ON foo (sort_index)
内重复sort_index
个值,并且除了明确之外,不应更改行的相对顺序。你不需要这个,解决方案更简单。)