sql >> Base de Datos >  >> RDS >> Sqlserver

Listado de todos los padres de elementos en una tabla de jerarquía como cadena SQL delimitada

Esto parece hacer el truco. La clave es darse cuenta de que podemos construir el camino hacia atrás y detenernos cuando ya no tengamos un padre para localizar:

DECLARE @t table (ID int not null, Name varchar(19) not null, ParentID int null)
insert into @t(ID,Name,ParentID) values
(1 ,'Alex',null),
(2 ,'John',null),
(3 ,'Don',1),
(4 ,'Philip',2),
(5 ,'Shiva',2),
(6 ,'San',3),
(7 ,'Antony',6),
(8 ,'Mathew',2),
(9 ,'Cyril',8),
(10,'Johan',9)

declare @search table (ID int not null)
insert into @search (ID) values (7),(10)

;With Paths as (
    select s.ID as RootID,t.ID,t.ParentID,t.Name, CONVERT(varchar(max),t.Name) as Path
    from
        @search s
            inner join
        @t t
            on
                s.ID = t.ID
    union all
    select p.RootID,t.ID,t.ParentID,p.Name, t.Name + '->' + p.Path
    from Paths p
            inner join
        @t t
            on
                p.ParentID = t.ID
)
select * from Paths where ParentID is null

Resultado:

RootID      ID          ParentID    Name                Path
----------- ----------- ----------- ------------------- ----------------------------
10          2           NULL        Johan               John->Mathew->Cyril->Johan
7           1           NULL        Antony              Alex->Don->San->Antony

(Lo dejé en columnas adicionales para ayudar a mostrar el estado final. Consultar el CTE sin filtrar también puede ser instructivo)

También advierto que normalmente no trabajaría con cadenas delimitadas si es posible; no es una gran representación cuando SQL Server tiene tipos diseñados para trabajar con múltiples valores.