我正在尝试重新排列分层数据集中的节点。这是按照您的预期结构化的。一个菜单项将有一个父菜单项,但在这种情况下...我正在一个父项下面的n个菜单项。如果我将菜单项从位置10移动到位置5,如下所示:
1 2 3 4 5 6 7 8 9 10 <-- Original
1 2 3 4 5 10 6 7 8 9 <-- New
有没有办法在一次操作中执行此操作而不是循环设置并将新位置与现有位置进行比较?我以为我看到了一些可以做到这一点的RANK功能,但我似乎无法找到它。
更新:以下是它的结构:
MENUID, PARENTID, SORT_RANK
1 100 1
2 100 2
3 100 3
4 100 4
5 100 5
如果我将MENUID 5向上移动三个位置,它将位于2到3之间,我想更新排序等级。有没有办法在不抓取parentID结构并循环遍历所有记录的情况下执行此操作。
答案 0 :(得分:1)
有两种可能性浮现在脑海中。
第一种方法是将移动项目的SORT_RANK更改为前一项和后一项的平均值,因此如果要移动MENUID = 5的项目,使其位于MENUID 2和MENUID 3之间,则设置SORT_RANK对于MENUID = 5到2.5。所以,如下所示:
UPDATE MENU_TABLE
SET SORT_RANK = ((SELECT SORT_RANK FROM MENU_TABLE WHERE MENUID = 2) +
(SELECT SORT_RANK FROM MENU_TABLE WHERE MENUID = 3)) / 2
WHERE MENUID = 5;
通过这种方式,您最终会得到带有非整数值的MENUID,但它们仍然可以正确排序。
第二个是做以下事情:
UPDATE MENU_TABLE
SET SORT_RANK = SORT_RANK + 1
WHERE PARENTID = 100 AND
SORT_RANK > 2;
UPDATE MENU_TABLE
SET SORT_RANK = 3
WHERE MENUID = 5;
然而,后一种方法需要两个陈述,这些陈述可能不是您想要的。
分享并享受。
答案 1 :(得分:0)
我不确定数据在层次结构中的结构是否重要。
您可以使用单个查询更新订单。假设rank_order
:R_START
处的项目转到:R_STOP
:
SQL> variable r_start NUMBER
SQL> variable r_stop NUMBER
SQL> EXEC :r_start := 5; :r_stop := 3;
PL/SQL procedure successfully completed
SQL> UPDATE mytable
2 SET sort_rank = CASE WHEN sort_rank = :R_START THEN :R_STOP
3 ELSE sort_rank + sign(:R_START - :R_STOP)
4 END
5 WHERE parentid = 100
6 AND sort_rank BETWEEN LEAST(:R_START, :R_STOP)
7 AND GREATEST(:R_START, :R_STOP);
3 rows updated
SQL> select * from mytable order by sort_rank;
MENUID PARENTID SORT_RANK
---------- ---------- ----------
1 100 1
2 100 2
5 100 3
3 100 4
4 100 5
答案 2 :(得分:0)
我将用一个问题回答你的问题;为什么要强制你的SORT_RANK
字段由整数组成?
如果SORT_RANK
字段只是NUMBER
,而不是NUMBER(10,0)
,则您可以将任何项目移动到任何位置,而无需重新排名问题。