Frage

Ich habe eine Tabelle wie folgt

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

Wenn ich einen childID als 5 geben, wird der parentid sein 1 (Ausgang)

Wenn ich einen childID als 9 geben, wird die parentid sein 7. (Ausgang)

d. die Wurzel parentid ist 0 und die Abfrage sollte dort anhalten.

Wie eine solche Abfrage lösen?

Bitte helfen.

War es hilfreich?

Lösung

Ich glaube, Sie Ihren child_id zu Knoten umbenennen sollen, Ihre parent_id child_of. Ihre Spalte Namensgebung ist ein bisschen verwirrend

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);

Dies funktioniert auf jedem CTE-fähigen 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

Ausgabe:

parent
7

[EDIT: flexibler und zukunftssicher] :

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    

Ausgabe:

to_find     found
5           1
9           7

Wenn Sie mit Postgres , könnte der obige Code zu verkürzen:

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

DISTINCT ON rock! : -)

Andere Tipps

Wenn Sie wollen nur die Wurzel ParentID, können Sie diese rekursive Funktion verwenden:

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

dann in der Hauptabfrage:

SELECT dbo.test_func(5)

Passing in 5 kehrt 1, 9 kehren 7 basierend auf Ihren zur Verfügung gestellten Daten. Wenn Sie jeden ParentID benötigen, die bis diese Kette ist, sollten Sie vielleicht einen CTE verwenden.

Ich denke, Sie eine rekursive Abfrage möchten, sollten Sie Common Table Expressions verwenden. Ich gebe Ihnen einen Link mit einem Beispiel sehr ähnlich, dass die, die Sie verwenden.

Ich denke, hier das ist Lösung. Es half mir vor einigen Monaten.

Ein einfaches Beispiel für die Eltern-ID bekommen eine gegebene Kind ID passend ist:

select parentid 
from MyTable 
where childid = 5

Doch für die obigen Daten, wird dies keine Datensätze zurück.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top