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.

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top