我正在努力进行分层SQL查询(使用Oracle)。假设我有一些带有唯一ID的小部件表。窗口小部件只能复制一次,我们会跟踪新窗口小部件中的父标识。例如,假设小部件100被复制并变为小部件101,然后是103,然后是105。
id parent_id
100
101 100
102
103 101
104
105 103
CREATE TABLE WIDGETS (ID NUMBER NOT NULL, PARENT_ID NUMBER);
INSERT INTO WIDGETS (ID, PARENT_ID) VALUES (100, null);
INSERT INTO WIDGETS (ID, PARENT_ID) VALUES (101, 100);
INSERT INTO WIDGETS (ID, PARENT_ID) VALUES (102, null);
INSERT INTO WIDGETS (ID, PARENT_ID) VALUES (103, 101);
INSERT INTO WIDGETS (ID, PARENT_ID) VALUES (104, null);
INSERT INTO WIDGETS (ID, PARENT_ID) VALUES (105, 103);
(102和104只是虚拟数据)
我正在尝试使用关系中的任何ID创建一个显示窗口小部件完整历史记录的查询。
因此,如果我为查询提供了“103”(或“100”......或“105”)的ID,我希望查询返回如下内容:
id parent_id
100
101 100
103 101
105 103
我尝试过使用CONNECT BY PRIOR,但我需要以ID开头才能使用start。例如,我可以显示完整的树,为查询提供原始ID:
select parent_id as from_id, id as to_id
from WIDGETS
start with id = 100
CONNECT BY PRIOR id = parent_id;
from_id to_id
null 100
100 101
101 103
103 105
但如果我不一定知道id的开头怎么办?是否可以找到原始ID,然后从那里获取完整的树?
答案 0 :(得分:1)
通过向后遍历树来计算开始,直到你碰到一片叶子。
SELECT parent_id AS from_id, ID AS to_id
FROM WIDGETS
START WITH ID =
( SELECT ID
FROM WIDGETS
WHERE CONNECT_BY_ISLEAF=1
START WITH ID = 105
CONNECT BY ID = PRIOR parent_id
)
CONNECT BY PRIOR ID = parent_id;
答案 1 :(得分:-1)
下面的@Input是您传递给存储过程的输入ID。试试这个,希望它有所帮助:
DECLARE @Parent int;
WHILE (Select @Parent = PARENT_ID From Widgets Where ID = @Input) Is NOT NULL
BEGIN
Set @Input = @Parent
END
Set @Parent = @Input
declare @Hierarchy table(Member int)
INSERT INTO @Hierarchy(Member) Values (@Parent)
WHILE (Select @Input = ID From Widgets Where PARENT_ID = @Parent) Is NOT NULL
BEGIN
SET @Parent = @Input
INSERT INTO @Hierarchy(Member) Values (@Parent)
END
Select * From @Hierarchy