2013-05-21 67 views
4

是否有任何好的算法,可以「填補」優先級(或任何其他)列表的差距? 例如差距填入優先級列+保持秩序

例如

我有一個結構如下表:

id | text | subcategory | priority 

和它充滿例如像這樣

1 | books | NULL | 1 
2 | dvds  | NULL | 2 
5 | action | 2 | 1 
8 | romantic | 2 | 2 
9 | fantasy | 1 | 1 
4 | sci-fi | 1 | 2 
6 | comics | 1 | 3 

在我的設計中有一個選項更改子類別,如果發生這種情況,則優先級設置爲「新」優先級,並且其值在當前子類別中爲最高。
例如 將「action(id:5)」子類別更改爲「books(id:1)」,其優先級爲4,即可,但現在「romantic(id:8)」行優先級爲2,並且它是唯一的子類別dvds(id:2)。

1 | books | NULL | 1 
2 | dvds  | NULL | 2 
8 | romantic | 2 | 2 
9 | fantasy | 1 | 1 
4 | sci-fi | 1 | 2 
6 | comics | 1 | 3 
5 | action | 1 | 4 

- >更改幻想(ID:9)子類別到DVD(ID:2),我的首要任務將是3

1 | books | NULL | 1 
2 | dvds  | NULL | 2 
8 | romantic | 2 | 2 
9 | fantasy | 2 | 3 
4 | sci-fi | 1 | 2 
6 | comics | 1 | 3 
5 | action | 1 | 4 

這是alrgiht,但我需要一個函數這將自行重新排序所有內容,所以我不必手動更改優先級列的值。所以優先列從1開始。

差距從第8行開始,第4行開始。 此外更改漫畫類別,然後將其更改回來,它會變得雜亂,會有正確的順序,但它不會看起來像我期望(用於管理目的)。

任何想法? 僞代碼邏輯會很好。

編輯 - 解決方案:僞代碼+邏輯

因爲我們知道在類的行數,我們可以做一個選擇是要通過優先級排序,這樣我們就可以分配適當數量的每個「新」優先。

例如:
有序select返回優先級如下:1,4,5,9,10
計數(選擇)= 5
所以 「新」 的優先級必須如下:1,2,3, 4,5.只需在foreach循環中分配新值即可。

自笨:
$這個 - > category_model-> getPriorities( 「2」),讓你所有優先級排序(ASC)一個子類的在我的情況2.

public function prioritize(){ 
    $p = $this->category_model->getPriorities("2"); 
     for ($i = 1; $i < count($p)+1; $i++) { 
      echo "new[".$i."]->id[".$p[$i-1]->id."]->old_value[".$p[$i-1]->priority."]<br>";  
     } 
} 

輸出:

new[1]->id[9]->old_value[1] 
new[2]->id[13]->old_value[3] 
new[3]->id[14]->old_value[5] 
new[4]->id[15]->old_value[8] 
new[5]->id[11]->old_value[10] 
+0

我會盡力幫忙,但首先我需要得到邏輯。優先級是什麼,以及爲什麼當改變4號行動的優先級時,它的子類別也改變了?或者它是一個反轉的依賴性,您正在更改子類別(因此books和dvd是類別?) –

+0

yep正如您可以看到的子類別是每個在子類別列中都有NULL的行,優先級僅用於在網站菜單上排序。 如果更改子類別,優先級更改爲新值:value =新子類別+1中的最高值優先級。(我在這裏發佈的這張表格組成了我的有點大,這張表格解釋了問題的目的) – Kyslik

回答

2

UPDATE表作爲TB1,如表TB2 SET tb2.priority = tb2.priority - 1 WHERE tb2.priority> tb1.priority AND tb1.text = '動作' AND tb2.subcategory = TB1 。子類別;

這應該解決了國內空白,具有較高的ID每一個項目,應該由1

砸即你在這個子類有:

| priority | 
| 1  | 
| 2  | 
| 3  | 
| 4  | 

,如果您將項目優先= 2

3和4將移動爲2和3

PS:這是僅針對差距的解決方案,因爲移動問題已在其他答案中解決。它應該在運動之前進行,因爲子類別後會改變它,而不會滿足WHERE子句(從舊的子類別的項目)


關於重新排序隨機差距:

讓我們說,我們有優先級:

5,10,11,12,18,20,我們希望儘可能使

1,2,3,4,5,6

所以最大數目這裏是20,這需要當它這樣做標記爲6

,最大數量爲18,這應該是5.

所以每次你使用UPDATE ... SET ... WHERE priority = MAX(priority)它會獲得最高優先級。

這裏是我的簡單的測試:

<?php 
for ($i = 6; $i>=1; $i--) { 
    echo "UPDATE table SET priority = $i WHERE priority = MAX(priority) AND subcategory = X;" . "<br/>"; 
} 
?> 

主要生產:

UPDATE table SET priority = 6 WHERE priority = MAX(priority) AND subcategory = X; // 20 becomes 6 
UPDATE table SET priority = 5 WHERE priority = MAX(priority) AND subcategory = X; // 18 becomes 5 
UPDATE table SET priority = 4 WHERE priority = MAX(priority) AND subcategory = X; // 12 becomes 4 
UPDATE table SET priority = 3 WHERE priority = MAX(priority) AND subcategory = X; // 11 becomes 3 
UPDATE table SET priority = 2 WHERE priority = MAX(priority) AND subcategory = X; // 10 becomes 2 
UPDATE table SET priority = 1 WHERE priority = MAX(priority) AND subcategory = X; // 5 becomes 1 

所以,你需要做一個選擇,你是選擇的子類別,把它代替「X」,然後您需要計算while循環的行數:

for ($i = $count_rows; $>=1; $i++) { ... 

當然,您需要將語句放在正確的查詢功能,而不是回顯它,但它是爲了測試目的。

+0

非常好,這應該是一個解決我的問題的確切辦法,但讓我們「泛化」,如果有人想要算法來填補空白,仍然有相同的順序**?我的意思是忘記改變類別和所有這些東西。差距沒有必要只是「高出一個數字」。優先級可能是5,10,11,12,18,20現在我希望它變成1,2,3,4,5,6 :)我知道你明白,但我正在尋找這個答案。 – Kyslik

+0

可能需要一些時間,才能使用純SQL。然而,我想簡單的循環在PHP中,我將編輯答案 –

+0

看到我的編輯;)做了同樣的事情(在codeigniter)@皇家Bg:燁它不是關於SQL與PHP結合... – Kyslik

1
SELECT @NewPriority := MAX(priority)+1 FROM table WHERE category='$NewCategory'; 
UPDATE table SET category='$NewCategory', prioroty = @NewPriority WHERE id='$Id'; 
+0

這是解決,我試圖找到解決**填補差距**,這是通過更改子類別創建的。正如你在我的例子中看到的那樣,在優先級列中存在差距,浪漫類別應該優先於1。2.我的意思是我可以將其改變爲manualy,但是我需要一個算法來自己做這件事。 – Kyslik

+0

這就是你需要的:http://lists.mysql.com/mysql/55481 解決方法在最後回覆 – peku33

+0

排序非常好的旁註感謝。記住優先級列有其目的(在任何改變之後,它必須有其最初的順序)!您提供的鏈接不是問題的解決方案,但它有很大幫助。 – Kyslik