早上好,
所以我遇到这种情况: 包含dataID,parentdataID和一些信息的数据表
MyTable
-Name
-WorkingPeriod
-ColorScheme
-ID
-parentID
为了说明,表格如下:
W0 (Always, Red)
--W1 (First time, red-blue)
----W2 (First step, red-blue-grey)
----W3 (Second step, red-blue-black)
------W4 (...)
--------W5 (...)
--W6 (Second time, red-green)
----W7 (First step, red-green-grey)
--W8 (Third time, red-pink)
对于每种情况,我都需要获得最接近root的节点。意思是:
希望我能够让自己清楚。 祝你有个美好的一天。
答案 0 :(得分:2)
如前所述,您可以使用分层查询完成它。您可以构建每个节点的路径,并从该字符串的根目录之前提取节点。这样的事情可能会帮助您获得最终解决方案:
WITH the_table AS (SELECT 'W0' item_id, NULL parent_id FROM DUAL
UNION
SELECT 'W1' item_id, 'W0' parent_id FROM DUAL
UNION
SELECT 'W2' item_id, 'W1' parent_id FROM DUAL
UNION
SELECT 'W3' item_id, 'W1' parent_id_idrent FROM DUAL
UNION
SELECT 'W4' item_id, 'W3' parent_id FROM DUAL
UNION
SELECT 'W5' item_id, 'W4' parent_id FROM DUAL
UNION
SELECT 'W6' item_id, 'W0' parent_id FROM DUAL
UNION
SELECT 'W7' item_id, 'W6' parent_id FROM DUAL
UNION
SELECT 'W8' item_id, 'W0' parent_id FROM DUAL)
SELECT item_id,
SYS_CONNECT_BY_PATH(item_id, '/') node_path,
SUBSTR(SYS_CONNECT_BY_PATH(item_id, '/'), 5, 2) just_before_root
FROM the_table
CONNECT BY PRIOR item_id = parent_id
START WITH parent_id IS NULL;
答案 1 :(得分:2)
完全归功于Pablomatico的起点,看看他的工作的扩展,包括处理不是2位数字的ID,并重新加入源以恢复之前的属性 - 根行:
convert
返回:
WITH the_table AS (SELECT 'W0' item_id, NULL parent_id, 'Red' colour FROM DUAL
UNION
SELECT 'W1' item_id, 'W0' parent_id , 'blue' colour FROM DUAL
UNION
SELECT 'W2' item_id, 'W1' parent_id, 'Grey' colour FROM DUAL
UNION
SELECT 'W3' item_id, 'W1' parent_id, 'Black' colour FROM DUAL
UNION
SELECT 'W4' item_id, 'W3' parent_id, 'Mauve' colour FROM DUAL
UNION
SELECT 'W5' item_id, 'W4' parent_id, 'Orange' colour FROM DUAL
UNION
SELECT 'W6' item_id, 'W0' parent_id, 'Green' colour FROM DUAL
UNION
SELECT 'W7' item_id, 'W6' parent_id, 'Grey' colour FROM DUAL
UNION
SELECT 'W8' item_id, 'W0' parent_id, 'Pink' colour FROM DUAL)
SELECT main_tab.item_id, main_tab.colour,main_tab.just_before_root, the_Table.colour
FROM
(SELECT item_id,
colour,
SYS_CONNECT_BY_PATH(item_id, '/') node_path,
CASE WHEN INSTR(SYS_CONNECT_BY_PATH(item_id, '/'),'/',1,2) = 0 THEN NULL
WHEN INSTR(SYS_CONNECT_BY_PATH(item_id, '/'),'/',1,2) != 0
AND INSTR(SYS_CONNECT_BY_PATH(item_id, '/'),'/',1,3) = 0
THEN SUBSTR(SYS_CONNECT_BY_PATH(item_id, '/'), INSTR(SYS_CONNECT_BY_PATH(item_id, '/'),'/',1,2)+1)
ELSE SUBSTR(SYS_CONNECT_BY_PATH(item_id, '/'), INSTR(SYS_CONNECT_BY_PATH(item_id, '/'),'/',1,2)+1,INSTR(SYS_CONNECT_BY_PATH(item_id, '/'),'/',1,3) - INSTR(SYS_CONNECT_BY_PATH(item_id, '/'),'/',1,2) - 1 ) END just_before_root
FROM the_table
CONNECT BY PRIOR item_id = parent_id
START WITH parent_id IS NULL) main_tab
left outer join the_table on main_tab.just_before_root = the_table.item_id;
答案 2 :(得分:0)
create or replace function getNodeCloserToRoot
(
p_given_node varchar2(50);
)
return varchar2
is
v_parent_node varchar2(50);
v_current_node varchar2(50) := p_given_node;
begin
select parentDataId
into v_parent_node
from MyTable
where dataId = v_current_node;
loop
exit when v_parent_node is null;
v_current_node := v_parent_node;
select parentDataId
into v_parent_node
from MyTable
where dataId = v_current_node;
end loop;
return v_current_node;
end;