【问题标题】:SQL hierarchical query: find full tree given an id of any parent-child (Oracle)SQL分层查询:查找给定任何父子ID的完整树(Oracle)
【发布时间】:2016-07-23 04:19:12
【问题描述】:

我正在努力进行分层 SQL 查询(使用 Oracle)。假设我有具有唯一 ID 的小部件表。一个小部件只能被复制一次,我们从新的小部件中跟踪父 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 with。例如,我可以显示为查询提供源 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,然后从那里获取完整的树?

【问题讨论】:

    标签: sql oracle oracle11g


    【解决方案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;

    【讨论】:

    • 如果您将 START WITH ID = 更改为 START WITH ID IN 它甚至可以处理添加对 (101, 104)。
    【解决方案2】:

    下面的@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
    

    【讨论】:

    • 为什么要使用存储过程进行简单的分层查询?绝对的缺点!
    • 我以为他正在尝试创建一个存储过程。
    • 你为什么会这样想?原始帖子中绝对没有任何内容表明 OP 正在寻找存储过程解决方案。
    • 我不知道我为什么会这样想,也不想解释我的想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多