Uscendo dalla tabella comune ricorsiva una volta che il set di risultati contiene un certo valore
-
10-10-2019 - |
Domanda
In base alla tabella seguente:
create table TreeNode
(
ID int not null primary key,
ParentID int null foreign key references TreeNode (ID)
)
Come potrei scrivere un'espressione di tabella comune per iniziare alla radice (DOVE ParentID IS NULL) e attraversare i suoi discendenti fino a quando il set di risultati contiene alcune nodo di destinazione (ad esempio, WHERE ID = n)? È facile iniziare in corrispondenza del nodo di destinazione ed attraversare verso l'alto per la radice, ma che non generare lo stesso set di risultati. Nello specifico, i nodi aventi lo stesso genitore del nodo di destinazione non sarebbe incluso.
Il mio primo tentativo è stato:
with Tree as
(
select
ID,
ParentID
from
TreeNode
where
ParentID is null
union all select
a.ID,
a.ParentID
from
TreeNode a
inner join Tree b
on b.ID = a.ParentID
where
not exists (select * from Tree where ID = @TargetID)
)
Il che dà l'errore: Recursive member of a common table expression 'Tree' has multiple recursive references.
Nota ??strong>:. Mi interessa solo in attraversamento top-down
Soluzione
UPDATE 2:
Un terzo tentativo che "traverse" l'albero in entrambe le direzioni.
Costruire un CTE di tutti ParentIDs
da Target
a root
. Quindi, selezionare la tree
nodes
cui ID
o compare nella short list Parent
.
--
;
WITH Tree
AS ( SELECT ID
,ParentID
FROM TreeNode
WHERE [ID] = @targetId
UNION ALL
SELECT a.ID
,a.ParentID
FROM TreeNode a
INNER JOIN Tree b ON b.ParentID = a.ID
)
SELECT *
FROM [dbo].[TreeNode] n
WHERE EXISTS (SELECT *
FROM [Tree] t
WHERE [t].[ID] = [n].[ID]
OR [t].[ID] = [n].[ParentID]
)