Gap填写优先级列+保持顺序

时间:2013-05-21 11:17:16

标签: php mysql codeigniter

是否有任何好的算法可以“填补”表格优先级(或任何其他)列的空白? e.g。

例如

我的表格结构如下:

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,即可,但现在“浪漫(id:8)”行优先级为2,且为1仅在子类别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

- >我将fantasy(id:9)子类别改为dvds(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开头。

Gaps从id为8的行开始。 此外,更改漫画类别,然后将其更改回来,它会变得一团糟,会有正确的顺序,但它看起来不像我期望的那样好(出于管理目的)。

有什么想法吗? 伪代码逻辑会很好。

编辑 - 解决方案:伪代码+逻辑

由于我们知道类别中的行数,因此我们可以按优先级排序选择,这样我们就可以为每个“新”优先级分配正确的数字。

例如:
有序选择返回优先级如下:1,4,5,9,10 count(select)= 5
所以“新”优先级必须如下:1,2,3,4,5。只需在foreach循环中指定新值即可。

因为它在codeigniter中:
$ this-> category_model-> getPriorities(“2”)在我的案例2中为您提供了一个子类别(ASC)的所有优先级。

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]

2 个答案:

答案 0 :(得分:2)

UPDATE表为tb1,表为tb2 SET tb2.priority = tb2.priority - 1 WHERE tb2.priority&gt; tb1.priority AND tb1.text ='action'AND tb2.subcategory = tb1.subcategory;

这应该可以解决这个差距,每个id值较高的项目应该减去1

即。你有这个子类别:

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

如果您移动优先级= 2的项目

3和4将移动为2和3

P.S。:这是仅针对差距的解决方案,因为移动问题已在另一个答案中得到解决。它应该在移动之前完成,因为子类别会在它之后发生变化,并且不会满足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

所以你需要在选择子类别的地方做一个SELECT,把它放在“X”上,然后你需要计算while循环的行数:

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

当然,您需要将语句放在正确的查询函数中,而不是回显它,但它是出于测试目的。

答案 1 :(得分:1)

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