是否有任何好的算法可以“填补”表的优先级(或任何其他)列中的空白? 例如
例子
我有一个结构如下所示的表:
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
在我的设计中,有一个更改子类别的选项,如果发生这种情况,优先级设置为"new"优先级,并且其值在当前所在的子类别中最高。
例如
将“action (id:5)”子类别更改为“books (id:1)”,它的优先级为 4,没关系,但现在“romantic (id:8)”行的优先级为 2,它是 1 和仅在子类别 dvd (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
这没问题,但我需要一个可以自行重新排序所有内容的函数,这样我就不必手动更改优先级列的值。所以优先级列从 1 开始。
间隙从 ID 为 8、4 的行开始。 此外,更改漫画类别然后再将其更改回来,它会变得很乱,但顺序会正确,但看起来不会像我预期的那样漂亮(出于管理目的)。
有什么想法吗? 伪代码 或逻辑 会很好。
编辑-解决方案:伪代码+逻辑
因为我们知道类别中的行数并且我们可以进行按优先级排序的选择,所以我们可以为每个"new"优先级分配正确的数字。
例如:
ordered select 返回优先级如下:1, 4, 5, 9, 10
计数(选择)= 5
所以"new"优先级必须如下:1、2、3、4、5。只需在 foreach 循环中为值分配新键即可。
因为它在 codeigniter 中:
在我的案例 2 中,$this->category_model->getPriorities("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]
最佳答案
更新表为 tb1,表为 tb2 SET tb2.priority = tb2.priority - 1 WHERE tb2.priority > 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++) { ...
当然,您需要将语句放在正确的查询函数中,而不是回显它,但这是为了测试目的。
关于php - 填空优先级列+保持顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16668689/