2010-04-17 16 views

Respuesta

24

Si usted tiene la raíz del árbol que desea, ¿no puedes usar:

DECLARE @root hierarchyID; 

SELECT @root = col 
FROM yourTable 
WHERE [whatever uniquely identifies this row] 

SELECT * 
FROM yourTable 
WHERE col.IsDescendantOf(@root) = 1 
+1

Marc - ¿Cómo se pueden limitar los descendientes a niveles de profundidad X? – IEnumerator

+0

@IEnumerator - puede usar 'col.GetLevel()' y agregarlo a la cláusula where – BornToCode

16

Vamos a suponer por mi ejemplo, que su mesa es algo como lo siguiente:

DECLARE TABLE MyTable 
(
    HID hierarchyid PRIMARY KEY, 
    ID int IDENTITY(1, 1), 
    SomeText varchar(50) 
); 

Si desea que todos los descendientes de un nodo con el ID 3, hasta un nivel máximo (de raíz) de 5:

DECLARE @searchNode hierarchyid; 

SELECT @searchNode = HID 
FROM MyTable 
WHERE ID = 3; 

SELECT * 
FROM MyTable 
WHERE HID.IsDescendantOf(@searchNode) 
AND HID.GetLevel() <= 5; 

Si en Stead desea 2 niveles de los niños bajo el nodo solicitado que se necesita para capturar el nivel de su nodo de búsqueda en la primera seleccionar y cambiar la comparación con algo como

WHERE HID.IsDescendantOf(@searchNode) = 1 
AND HID.GetLevel() <= (@searchLevel + 2); 
0

Soy un fan de CTE para este tipo de consulta porque tiene cierta flexibilidad para devolver solo a los hijos, solo a los padres, o ambos, dependiendo de cómo se estructura el código. En este caso, estoy devolviendo una UNIÓN de ambos, solo por ejemplo.

declare @MyTable table 
(
    ID int not null, 
    HierId hierarchyid null 
); 

declare @id int 
set @id = 1 

;with parent (TenantId, HierId, IsParent) as 
(
    select 
     t.ID 
     ,t.HierId 
     ,cast(1 as bit) as IsParent 
    from @MyTable t 
    where t.ID = @id 
), children as 
(
    select 
     t.ID 
     ,t.HierId 
     ,cast(0 as bit) as IsParent 
    from 
     @MyTable t 
     inner join parent p 
      on t.HierId.IsDescendantOf(p.HierId) = 1 
) 
select 
    * 
from parent 
UNION 
select * 
from children 
Cuestiones relacionadas