如何在没有循环的情况下重新排列分层数据?
Posted
技术标签:
【中文标题】如何在没有循环的情况下重新排列分层数据?【英文标题】:How can I re-rank hierarchical data without a loop? 【发布时间】:2013-03-07 14:42:19 【问题描述】:我正在尝试重新排列分层数据集中的节点。这是您所期望的结构。一个菜单项将有一个父菜单项,但在这种情况下......我在一个父项下大约有 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 结构并遍历所有记录的情况下做到这一点。
【问题讨论】:
我不确定我是否理解这些数据的层次结构。你能详细说明一下吗? @VincentMalgrat 现在看看... 【参考方案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;
但是,后一种方法需要两个语句,这可能不是您想要的。
分享和享受。
【讨论】:
【参考方案2】:我不确定数据按层次结构构造这一事实是否重要。
您可以通过一个查询来更新您的订单。假设 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
【讨论】:
【参考方案3】:我会用一个问题来回答你的问题;你为什么要求你的SORT_RANK
字段由整数组成?
如果SORT_RANK
字段只是NUMBER
,而不是NUMBER(10,0)
,您可以将任何项目移动到任何位置,而不会出现重新排名问题。
【讨论】:
以上是关于如何在没有循环的情况下重新排列分层数据?的主要内容,如果未能解决你的问题,请参考以下文章
React Native - 如何在没有完全重新渲染的情况下在 ListView 中添加和附加数据
TypeError:“sqlite3.Cursor”对象不可下标。如何在没有for循环的情况下打印sql选择数据[重复]