Come ottenere il genitore dato un figlio in SQL Server 2005
-
12-09-2019 - |
Domanda
Ho una tabella come questo
childid parentid
------------------------
1 0
2 1
3 2
4 2
5 3
6 4
7 0
8 7
9 8
10 1
Se io do una childid come 5, il parentid sarà 1 (output)
Se do un childid come 9, il parentid sarà 7. (output)
vale a dire. la parentid radice è 0 e la query dovrebbe fermarsi qui.
Come risolvere una query?
Si prega di aiutare.
Soluzione
Credo che si dovrebbe rinominare la child_id al nodo, il vostro parent_id a child_of. La vostra denominazione colonna è un po 'di confusione
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);
Questo funziona su qualsiasi RDBMS CTE-grado :
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: a prova di futuro più flessibile 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 stai usando Postgres , il codice di cui sopra potrebbe essere ridotto a:
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 sulle rocce! : -)
Altri suggerimenti
Se invece si è alla ParentID radice, è possibile utilizzare questa funzione ricorsiva:
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
quindi nella query principale:
SELECT dbo.test_func(5)
Passaggio in 5 restituisce 1, 9 Restituisce 7, sulla base di dati forniti. Se avete bisogno di ogni ParentID che è fino a catena che, probabilmente si dovrebbe utilizzare un CTE.
Penso che si desidera una query ricorsive, si consiglia di utilizzare espressioni di tabella comuni. Vi darò un collegamento con un esempio molto simile che quello che si sta utilizzando.
qui è la soluzione. Mi ha aiutato qualche mese fa.
Un semplice esempio di ottenere l'ID genitore corrispondenza di un determinato ID bambino è:
select parentid
from MyTable
where childid = 5
Tuttavia, per i dati di cui sopra, questo restituirà nessun record.