Como obter o pai deu um filho no SQL Server 2005
-
12-09-2019 - |
Pergunta
Eu tenho uma tabela como esta ??p>
childid parentid
------------------------
1 0
2 1
3 2
4 2
5 3
6 4
7 0
8 7
9 8
10 1
Se eu dar um childid como 5, o parentid será de 1 (saída)
Se eu dou um childid como 9, o parentid será 7. (saída)
i. o parentid raiz é 0 e a consulta deve parar por aí.
Como resolver essa consulta?
Por favor, ajuda.
Solução
Eu acho que você deve renomear sua child_id ao nó, o parent_id para child_of. Sua nomeação coluna é um pouco confuso
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);
Isso funciona em qualquer RDBMS CTE-capable :
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
Output:
parent
7
[EDIT: à prova de futuro mais flexível e] :
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
Output:
to_find found
5 1
9 7
Se você estiver usando Postgres , o código acima poderia ser reduzido para:
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
Em Rochas DISTINTAS! : -)
Outras dicas
Se tudo que você quer é o ParentID raiz, você pode usar esta função recursiva:
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
, em seguida, em sua consulta principal:
SELECT dbo.test_func(5)
Passando em 5 retorna 1, 9 Retorna 7 com base em seus dados fornecidos. Se você precisa de cada ParentID que é até essa cadeia, você provavelmente deve usar uma CTE.
Eu acho que você quer uma consulta recursiva, você deve usar expressões de tabela comum. Vou dar-lhe um link com um exemplo muito semelhante que o que você está usando.
aqui é o solução. Ele me ajudou a alguns meses atrás.
Um simples exemplo de obter o ID pai combinando um determinado ID criança é:
select parentid
from MyTable
where childid = 5
No entanto, para os dados acima, este retornará nenhum registro.