如何在没有循环的情况下重新排序分层数据?

时间:2013-03-07 14:42:19

标签: plsql oracle10g oracle11g

我正在尝试重新排列分层数据集中的节点。这是按照您的预期结构化的。一个菜单项将有一个父菜单项,但在这种情况下...我正在一个父项下面的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结构并循环遍历所有记录的情况下执行此操作。

3 个答案:

答案 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),则您可以将任何项目移动到任何位置,而无需重新排名问题。