2010-03-02 7 views
5

Dada la siguiente consulta recursiva:recursivo para consultas - Sólo seleccione los nodos en los nodos hoja representan datos activos

WITH DepartmentHierarchy (DepartmentID, Name, IsInactive, IsSpecial, ParentId, HierarchyLevel) AS 
(
    -- Base case 
    SELECT 
     DepartmentId, 
     Name, 
     IsInactive, 
     IsSpecial, 
     ParentId, 
     1 as HierarchyLevel 
    FROM StoreDepartment 
    WHERE ParentId IS NULL 

    UNION ALL 

    -- Recursive step 
    SELECT 
     d.DepartmentId, 
     d.Name, 
     d.IsInactive, 
     d.IsSpecial, 
     d.ParentId, 
     dh.HierarchyLevel + 1 AS HierarchyLevel 
    FROM StoreDepartment d 
     INNER JOIN DepartmentHierarchy dh ON 
     d.ParentId = dh.DepartmentId 
) SELECT * FROM DepartmentHierarchy 

soy capaz de seleccionar los datos que se parece a esto:

DepartmentId, Name, IsInactive, IsSpecial, ParentId, HeirarchyLevel 
1, Store, 0, 0, NULL, 1 
2, Main Department 1, 0, 1, 2 
3, Main Department 2, 0, 1, 2 
4, Sub For Main 1, 0, 2, 3 

También, asumir una tabla existe con DepartmentId y ItemId (por ejemplo: DepartmentItemRelationship). Los nodos de la hoja de la jerarquía del departamento se combinan con elementos aquí.

Quiero que mi consulta recursiva solo devuelva nodos (en cualquier nivel) que tengan al menos un nodo hoja debajo de ellos con una coincidencia en la tabla de relación entre departamento/elemento. Estos nodos podrían tener 6 o 7 niveles de inactividad, por lo que no estoy seguro de cómo modificaría mi consulta para asegurarme de incluirlos.

Gracias, Kyle

+0

Kyle, si tiene un nodo hoja que cumple el requisito en un nivel 6, ¿desea mostrar los 5 departamentos por encima de ese nodo? –

Respuesta

3

Se puede crear una columna camino que sigue la pista de la jerarquía. Luego, solo puede agregar los nodos secundarios que tienen una coincidencia en la tabla DepartmentItemRelationship. Y finalmente obtenga solo los nodos que al menos tienen un hijo.

intentar algo como esto:

WITH DepartmentHierarchy (DepartmentID, Name, IsInactive, IsSpecial, ParentId, HierarchyLevel) AS 
(
    -- Base case 
    SELECT 
     '/'+cast(DepartmentId as varchar(max)) as [path] 
     DepartmentId, 
     Name, 
     IsInactive, 
     IsSpecial, 
     ParentId, 
     1 as HierarchyLevel 
    FROM StoreDepartment 
    WHERE ParentId IS NULL 

    UNION ALL 

    -- Recursive step 
    SELECT 
     dh.[path] +'/'+ cast(d.DepartmentId as varchar(max)) as [path] 
     d.DepartmentId, 
     d.Name, 
     d.IsInactive, 
     d.IsSpecial, 
     d.ParentId, 
     dh.HierarchyLevel + 1 AS HierarchyLevel 
    FROM StoreDepartment d 
     INNER JOIN DepartmentHierarchy dh ON 
     d.ParentId = dh.DepartmentId 
    where exists (select top 1 1 
        from DepartmentItemRelationship di 
        where di.DepartmentId = d.DepartmentId) 
) 
SELECT * 
FROM DepartmentHierarchy dh 
where exists (select top 1 1 
       from DepartmentHierarchy 
       where charindex('/'+dh.DepartmentID+'/',[path]) > 0) 
+0

Esto funciona brillantemente. El hecho de tener el camino de recorrido a través del árbol me ayudará a resolver qué registros debo devolver. (nota: eliminé la cláusula 'TOP' ya que no estaba permitido en una consulta recursiva). –

1

Si he entendido bien, desea que todos los nodos que son exactamente un nivel por encima del nivel de hoja?

No necesita realmente una consulta recursiva para esto. Todo lo que debe hacer es encontrar primero los nodos de hojas, luego seleccionar todos los padres.

WITH LeafNodeParents AS 
(
    SELECT DISTINCT ParentId 
    FROM StoreDepartment 
    WHERE DepartmentId NOT IN 
    (
     SELECT DISTINCT ParentId FROM StoreDepartment 
    ) 
) 
SELECT d.DepartmentId, d.Name, d.IsInactive, d.IsSpecial, d.ParentId 
FROM LeafNodeParents p 
INNER JOIN StoreDepartment d 
    ON d.DepartmentId = p.ParentId 

Lo único que no le dirá es el nivel. No estoy seguro de lo mucho que lo necesitas. Si no lo hace, esto debería funcionar mucho mejor que la versión recursiva; si lo hace, parece que la consulta de José está bien para eso (a juzgar por un rápido vistazo).

+0

Gracias por la sugerencia, acepté la otra respuesta porque me permitió obtener datos de todos los nodos. Todavía aprecio (y voté a favor) tu respuesta. –

Cuestiones relacionadas