2009-10-17 23 views
4

如果我有以下表&數據允許我們使用sort_index排序:MySQL的更新排序索引列到移動項目

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); 

我希望能夠做到以下幾點以最有效方式:

  1. 移動FOO條目到給定位置(由bar_id作用域)
    • 確保sort_index始終爲1索引,有沒有間隙
    • 您應該能夠將項目移至開始和列表和規則#2仍應適用結束
    • 應在查詢全部完成,儘可能少的可能(因爲臺可能是非常大的循環在他們做個別UPDATE s的不理想)

爲了澄清什麼,我試圖做的,讓我們假設該表是空的,所以我們有以下數據:

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 

然後如果我們做以下動作

  • 富1至sort_index 3
  • FOO 7 sort_index 1個
  • 富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 
+0

爲了澄清你的問題:給定上面的插入,你希望在開始時插入另一個'bar_id' = 1的行,導致所有後續行的更新(列'sort_index') 'bar_id'是1的位置? – tangens 2009-10-17 08:56:55

+0

總結您的要求,對於任何一組「bar_id」,sort_index必須從零開始,並加1,直到最大的sort_index數字。你想完全在MySQL中執行任何移動/添加/刪除操作? – 2009-10-17 08:58:40

回答

3

你應該能夠做到這一點的一個查詢:沿UPDATE foo SET sort_index = sort_index + 1 WHERE bar_id == b AND sort_index < s1 AND sort_index >= s2,其中b是該行的bar_id要移動的東西線,s1是當前sort_index那一行,而s2是你想要移動到的sort_index。然後,您只需更改該行的sort_index

您可能想要在事務中執行兩個查詢。另外,如果您使用CREATE INDEX foo_index ON foo (sort_index)之類的東西在sort_index上創建索引,它可能會加快速度。 (順便說一句,在這裏我假設你不希望在給定的bar_id內重複sort_index值,並且行的相對順序不應該被改變,除非明確的。如果你不需要這個,解決方法更簡單:)

+0

這是相當時髦,幾乎完美的作品。然而,如果我想將一個項目移動到列表的末尾,那麼它不起作用,因爲我最終得到的結果是2與sort_index相同並且沒有填充舊的sort_index(例如,如果我將項目從3移動到5 I以sort_index爲5結尾2​​,沒有3)。 – DEfusion 2009-10-17 10:53:18

+1

實際上有一些情況(如移動到列表的末尾),你需要使用它來代替:UPDATE foo SET sort_index = sort_index - 1 WHERE bar_id == b AND sort_index> s1 AND sort_index <= s2 – DEfusion 2009-10-17 11:27:04

+0

啊是的,當然。事實上,這不僅僅是當你將它移動到列表的最後,它只是當你將它向前移動時。 – David 2009-10-17 11:55:44