Question

J'ai une table comme ceci

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

Si je donne un childID comme 5, le parentid sera 1 (sortie)

Si je donne un childID comme 9, le parentid sera 7. (sortie)

i.e.. la parentid racine est 0 et la requête doit arrêter.

Comment résoudre une telle requête?

S'il vous plaît aider.

Était-ce utile?

La solution

Je pense que vous devez renommer votre child_id au nœud, votre parent_id à child_of. Votre désignation de colonne est un peu déroutant

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

Cela fonctionne sur toutes SGBDR CTE compatible :

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

Sortie:

parent
7

[EDIT: plus souple et à l'épreuve] :

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    

Sortie:

to_find     found
5           1
9           7

Si vous utilisez Postgres , le code ci-dessus pourrait être raccourci à:

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 sur les rochers! : -)

Autres conseils

Si vous voulez simplement la ParentID racine, vous pouvez utiliser cette fonction récursive:

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

puis dans votre requête principale:

SELECT dbo.test_func(5)

Passe dans 5 rendements 1, 9 renvoie 7 basé sur les données fournies. Si vous avez besoin chaque ParentID qui est jusqu'à cette chaîne, vous devriez probablement utiliser un CTE.

Je pense que vous voulez une requête récursive, vous devez utiliser des expressions de table commune. Je vais vous donner un lien avec un exemple très similaire que celui que vous utilisez.

Je pense que est le Solution. Il m'a aidé il y a quelques mois.

Un simple exemple d'obtenir l'ID parent correspondant à un ID enfant donné est:

select parentid 
from MyTable 
where childid = 5

Cependant, pour les données ci-dessus, cela renvoie aucun enregistrement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top