是否有任何好的算法可以“填补”表格优先级(或任何其他)列的空白? 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]
答案 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';