sql sql-server db2 hierarchical

Consulta jerárquica única para todos los antepasados ​​/ padres e hijos(DB2/SQLServer)



sql-server hierarchical (3)


Encontré la solución para Oracle usando UNION ALL en dos consultas jerárquicas CONNECT BY, una buscando a los antepasados ​​y otra a los niños.
Quiero lograr lo mismo para DB2 y SQL Server .
Sé que un elemento podría ser una raíz, una rama o una hoja en la jerarquía. Necesito buscar toda su jerarquía.

Supongamos que tengo itemid = ''item3'' y class = ''my class'' , necesito encontrar sus ancestros e hijos, se me ocurrió:

with ancestor (class, itemid, parent, base, depth) as ( select root.class, root.itemid, root.parent, root.itemid, 0 from item root where root.class = ''myclass'' and root.itemid = ''item3'' -- union all -- select child.class, child.itemid, child.parent, root.base, root.depth+1 -- from ancestor root, item child -- where child.class = root.class -- and child.parent = root.itemid union all select parent.class, parent.itemid, parent.parent, parent.itemid, root.depth-1 from ancestor root, item parent where parent.class = root.class and parent.itemid = root.parent ) select distinct class, itemid, parent, base, depth from ancestor order by class, base, depth asc, itemid

Quiero un resultado como este:

class itemid parent base depth myclass item1 null item3 -2 myclass item2 item1 item3 -1 myclass item3 item2 item3 0 myclass item4 item3 item3 1 myclass item5 item5 item3 2

Si se ejecuta el SQL anterior obtengo los ancestros bien. Ahora si elimino los comentarios, parece estar en un bucle infinito. Debe haber una manera de hacer que eso funcione.
Puedo obtener los resultados en jerarquía de una dirección (antecesor o hijos) bien, pero no puedo obtener ambos en una sola consulta.
¿Alguna vez alguien intentó algo así?

Gracias


En la consulta comentada, debes mencionar que parent.parent es NULL

Por favor revisa este http://msdn.microsoft.com/en-us/library/ms186243.aspx

USE AdventureWorks2008R2; GO WITH DirectReports (ManagerID, EmployeeID, Title, DeptID, Level) AS ( -- Anchor member definition SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID, 0 AS Level FROM dbo.MyEmployees AS e INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh ON e.EmployeeID = edh.BusinessEntityID AND edh.EndDate IS NULL WHERE ManagerID IS NULL UNION ALL -- Recursive member definition SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID, Level + 1 FROM dbo.MyEmployees AS e INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh ON e.EmployeeID = edh.BusinessEntityID AND edh.EndDate IS NULL INNER JOIN DirectReports AS d ON e.ManagerID = d.EmployeeID ) -- Statement that executes the CTE SELECT ManagerID, EmployeeID, Title, DeptID, Level FROM DirectReports INNER JOIN HumanResources.Department AS dp ON DirectReports.DeptID = dp.DepartmentID WHERE dp.GroupName = N''Sales and Marketing'' OR Level = 0; GO


Si no te importa hacerlo usando dos instrucciones WITH , el siguiente devuelve todo tu árbol de jerarquía.

Datos de prueba

DECLARE @item TABLE ( class VARCHAR(32) , itemid VARCHAR(32) , parent VARCHAR(32) ) INSERT INTO @item VALUES (''myclass'', ''item1'', null) , (''myclass'', ''item2'', ''item1'') , (''myclass'', ''item3'', ''item2'') , (''myclass'', ''item4'', ''item3'') , (''myclass'', ''item5'', ''item4'')

Declaración de SQL

;WITH children AS ( SELECT class , itemid , parent , base = itemid , depth = 0 FROM @item WHERE class = ''myclass'' AND itemid = ''item3'' UNION ALL SELECT children.class , i.itemid , i.parent , children.base , children.depth + 1 FROM children INNER JOIN @item i ON i.parent = children.itemid AND i.class = children.class ) , parents AS ( SELECT * FROM children WHERE depth = 0 UNION ALL SELECT parents.class , i.itemid , i.parent , parents.base , parents.depth - 1 FROM parents INNER JOIN @item i ON i.itemid = parents.parent AND i.class = parents.class ) SELECT * FROM children UNION SELECT * FROM parents ORDER BY depth


use 3 CTE

with ancestors as (...) ,children as (...) ,all_ as (select * from ancestors union all select * from children) select * from all_