Wie die Eltern bekommen ein Kind in SQL Server 2005 gegeben
-
12-09-2019 - |
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.
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.