【发布时间】:2009-10-17 08:45:53
【问题描述】:
如果我有下表和数据允许我们使用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);
我希望能够以最有效的方式执行以下操作:
- 将 foo 条目移动到给定位置(由 bar_id 限定)
- 确保
sort_index始终为 1 索引并且没有间隙 - 您应该能够将项目移动到列表的开头和结尾,并且仍应应用规则 #2
- 它应该完全在查询中完成,并且尽可能少(因为集合可能非常大,并且在它们上循环执行单独的
UPDATEs 并不理想)
- 确保
为了澄清我想要做什么,我们假设表格是空的,所以我们有以下数据:
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
如果我们要进行以下动作
- Foo 1 到 sort_index 3
- Foo 7 到 sort_index 1
- Foo 5 到 sort_index 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
【问题讨论】:
-
为了澄清您的问题:鉴于上面的插入,您希望在开头插入另一行
bar_id=1,从而导致所有后续行的更新(列sort_index)@ 987654331@是1? -
总结您的要求,对于任何“bar_id”集,sort_index 必须从零开始并以 1 递增,直到最大的 sort_index 数。并且您想完全在 MySQL 中为任何移动/添加/删除操作执行此操作?
标签: mysql sql sql-update sql-order-by