问题
Initial scenario
My software uses a tree data structure, and I store it in SQL. I use the abstraction called Adjacency List which consists of each row storing ID
and ParentID
.
ID
is Primary Key and ParentID
is a Foreign Key to the same table.
The problem
I want to "convert" my SQL abstraction to Path Enumeration. It consists of each row storing ID
and a varchar
field storing the path of the IDs, from the root to the current row. For example, the Path
field of the row with ID = 6
in this tree:
Would be /1/2/4/6/
. More details here, by the name Lineage Column.
Question
How do I build a column Path
from an existing database that only has ID
and ParentID
?
回答1:
SQL Server 2005 onwards should support the following:
WITH
recursed_tree AS
(
SELECT
IDObject,
concat('/', cast(IDObject as varchar(100))) AS Path
FROM
tbObject
WHERE
ParentID IS NULL
UNION ALL
SELECT
next.IDObject,
concat(prev.Path, '/', cast(next.IDObject as varchar(100))) AS Path
FROM
recursed_tree AS prev
INNER JOIN
tbObject AS next
ON prev.IDObject = next.ParentID
)
SELECT
*
FROM
recursed_tree
回答2:
I came up with this SQL Server query:
[ tbObjectHierarchy
has a FK and PK called IDObject
and a varchar
called Path
]
declare @T as table (IDObject int, Path varchar(500))
declare @T2 as table (IDObject int, Path varchar(500))
insert into tbObjectHierarchy(IDObject, Path)
select o.IDObject, concat('/', cast(o.IDObject as varchar(100)), '/') as Path
from tbObject as o
where o.ParentID is null
insert into @T (IDObject, Path)
select o.IDObject, concat(h.Path, cast(o.IDObject as varchar(100)), '/') as Path
from tbObject as o
inner join tbObjectHierarchy as h
on o.ParentID = h.IDObject
while exists (select top 1 * from @T)
begin
insert into tbObjectHierarchy (IDObject, Path)
select t.IDObject, t.Path
from @T as t
delete from @T2
insert into @T2
select o.IDObject, concat(t.Path, cast(o.IDObject as varchar(100)), '/') as Path
from tbObject as o
inner join @T as t
on o.ParentID = t.IDObject
delete from @T
insert into @T
select * from @T2
end
来源:https://stackoverflow.com/questions/23368657/build-enumeration-path-from-adjacency-list-in-sql