2008-10-24 70 views
11

Hace mucho tiempo, cuando trabajaba en una tienda Oracle, daba por sentado el CONNECT_BY. Ahora estoy trabado trabajando con SQL Server 2005 y tengo algunas jerarquías de objetos desagradables. Específicamente, tenemos una tabla de autorreferencia en la que todos los registros secundarios tienen una columna con la identificación de sus padres. Actualmente tenemos una vista que asigna a los niños a niveles en la jerarquía y una desagradable consulta que hace el trabajo pesado para conectar a los padres con sus hijos. Si bien este método funciona, está lejos de ser elegante y huele a mancha. Solo tengo curiosidad de cómo otras personas recuperan datos jerárquicos de SQL Server 2005.Consultas jerárquicas en SQL Server 2005

Respuesta

1

en SQL Server 2005 puede usar Common Table Expressions (CTE) para esto.

+0

la fuerza recursiva es CON() usted. har har har. –

+0

¿Podría mostrar un ejemplo? –

25

Esto crea su tabla jerárquica típica y utiliza un CTE para seleccionar la estructura jerárquica y crear una ruta para cada elemento.

CREATE TABLE tblHierarchy (ID int, ParentID int NULL, Name varchar(128)); 

INSERT INTO tblHierarchy VALUES (1, NULL, '1'); 
INSERT INTO tblHierarchy VALUES (2, NULL, '2'); 
INSERT INTO tblHierarchy VALUES (3, NULL, '3'); 
INSERT INTO tblHierarchy VALUES (4, 1, '1.1'); 
INSERT INTO tblHierarchy VALUES (5, 1, '1.2'); 
INSERT INTO tblHierarchy VALUES (6, 4, '1.1.1'); 

WITH Parent AS 
(
    SELECT 
     ID, 
     ParentID, 
     Name AS Path 
    FROM 
     tblHierarchy 
    WHERE 
     ParentID IS NULL 

    UNION ALL 

    SELECT 
     TH.ID, 
     TH.ParentID, 
     CONVERT(varchar(128), Parent.Path + '/' + TH.Name) AS Path 
    FROM 
     tblHierarchy TH 
    INNER JOIN 
     Parent 
    ON 
     Parent.ID = TH.ParentID 
) 
SELECT * FROM Parent 

SALIDA:

ID ParentID Path 
1 NULL  1 
2 NULL  2 
3 NULL  3 
4 1  1/1.1 
5 1  1/1.2 
6 4  1/1.1/1.1.1 
3

Para su información. SQL Server 2008 admite un nuevo tipo de datos Hierarchy ID.

2
+0

Sí, los conjuntos anidados son definitivamente el camino a seguir para obtener jerarquías ilimitadas en un RDBMS. La descripción de Sitepoint hace que suene un poco más complicado de lo que realmente es, y las implementaciones se pueden simplificar, por ejemplo. teniendo una 'orden de rango' y 'rango de próximo hermano' en lugar de 'izquierda' y 'derecha'. – bobince

3

haber usado tanto, encontré CONNECT BY es algo más flexible y más fácil de usar que CTE. La pregunta no es diferente a una que respondí hace unas semanas. Consulte Here para obtener una breve comparación de CONNECT BY y CTE y Here para ver un ejemplo de una consulta que utiliza CTE.

+0

Difícil suerte de que CONNECT BY no exista en MSSQL. –

0

para atravesar la profundidad de la jerarquía primero y luego al siguiente nivel hermanos, CTE se puede utilizar:

declare @tempTable TABLE 
(
    ORGUID int, 
    ORGNAME nvarchar(100), 
    PARENTORGUID int, 
    ORGPATH nvarchar(max) 
) 

;WITH RECORG(ORGuid, ORGNAME, PARENTORGUID, ORGPATH) 
as 
(
    select 
     org.UID, 
     org.Name, 
     org.ParentOrganizationUID, 
     dbo.fGetOrganizationBreadcrumbs(org.UID) 
    from Organization org 
    where org.UID =1 

    union all 

    select 
     orgRec.UID, 
     orgRec.Name, 
     orgRec.ParentOrganizationUID, 
     dbo.fGetOrganizationBreadcrumbs(orgRec.UID) 
    from Organization orgRec 
    inner join RECORG recOrg on orgRec.ParentOrganizationUID = recOrg.ORGuid 

) 
insert into @tempTable(ORGUID, ORGNAME, PARENTORGUID,ORGPATH) 

select ORGUID, ORGNAME, PARENTORGUID,ORGPATH 
from RECORG rec 

select * 
from @tempTable where ORGUID in(select MIN(tt.ORGUID) 
           from @tempTable tt 
           group by tt.PARENTORGUID) 
Cuestiones relacionadas