3

我有一张这样的桌子

childid      parentid
------------------------
1       0
2       1
3       2
4       2
5       3
6       4
7       0
8       7
9       8
10      1

如果我将 childid 设为 5,则 parentid 将为 1(输出)

如果我将 childid 设为 9,则 parentid 将为 7。(输出)

即根 parentid 为 0,查询应该停在那里。

如何解决这样的查询?

请帮忙。

4

4 回答 4

5

我认为您应该将您的 child_id 重命名为节点,将您的 parent_id 重命名为 child_of。您的列命名有点混乱

create table stack_overflow
(
node int, child_of int
);


insert into stack_overflow(node, child_of) values
(1,0),
(2,1),
(3,2),
(4,2),
(5,3),
(6,4),
(7,0),
(8,7),
(9,8),
(10,1);

这适用于任何支持 CTE 的 RDBMS

with find_parent(parent, child_of, recentness) as
(
    select node, child_of, 0 
    from stack_overflow
    where node = 9
    union all
    select i.node, i.child_of, fp.recentness + 1
    from stack_overflow i
    join find_parent fp on i.node = fp.child_of
)
select top 1 parent from find_parent 
order by recentness desc

输出:

parent
7

[编辑:更灵活和面向未来]

with find_parent(node_group, parent, child_of, recentness) as
(
    select node, node, child_of, 0
    from stack_overflow
    where node in (5,9)
    union all
    select fp.node_group, i.node, i.child_of, fp.recentness + 1
    from stack_overflow i
    join find_parent fp on i.node = fp.child_of
)
select q.node_group as to_find, parent as found 
from find_parent q 
join
(
    select node_group, max(recentness) as answer
    from find_parent
    group by node_group 
) as ans on q.node_group = ans.node_group and q.recentness = ans.answer 
order by to_find    

输出:

to_find     found
5           1
9           7

如果您使用的是Postgres,上面的代码可以缩短为:

with recursive find_parent(node_group, parent, child_of, recentness) as
(
    select node, node, child_of, 0
    from stack_overflow
    where node in (5,9)
    union all
    select fp.node_group, i.node, i.child_of, fp.recentness + 1
    from stack_overflow i
    join find_parent fp on i.node = fp.child_of
)
select distinct on (node_group) node_group as to_find, parent as found 
from find_parent 
order by to_find, recentness desc

岩石上的独特之处!:-)

于 2009-07-10T05:48:54.400 回答
4

如果你想要的只是根 ParentID,你可以使用这个递归函数:

CREATE FUNCTION test_func
(
    @ParentID int
)
RETURNS int
AS
BEGIN
    DECLARE @result int;
    DECLARE @childID int;

    SET @childID = (SELECT ChildID FROM YourTable WHERE ParentID = @ParentID)

    IF (@childID = 0)
        SET @result = @ParentID
    ELSE
        SET @result = dbo.test_func(@childID)

    RETURN @result    
END
GO

然后在您的主要查询中:

SELECT dbo.test_func(5)

传入 5 返回 1, 9 根据您提供的数据返回 7。如果您需要该链上的每个 ParentID,您可能应该使用 CTE。

于 2009-07-09T16:35:47.437 回答
0

我认为你想要一个递归查询,你应该使用公用表表达式。我将为您提供一个链接,其中包含与您正在使用的示例非常相似的示例。

我认为是解决方案。几个月前它帮助了我。

于 2009-07-09T16:33:11.920 回答
0

获取与给定子 ID 匹配的父 ID 的简单示例是:

select parentid 
from MyTable 
where childid = 5

但是,对于上面的数据,这将不返回任何记录。

于 2009-07-09T16:34:17.173 回答