我有一张如下表:
ID Type ParentID
001 C 007
002 C 005
003 B 007
004 C 008
005 R NULL
006 C 004
007 B 004
008 R 009
009 X NULL
类型层次结构是X> R> C = B.我需要找到B和C的所有记录'R父级。 挑战是一些B或C记录的父母是B或C,X需要被排除在外。 结果将是:
ID Type ParentID MasterParentID
001 C 007 008
002 C 005 005
003 B 007 008
004 C 008 008
005 R NULL NULL
006 C 004 008
007 B 004 008
008 R 009 NULL
009 X NULL NULL
有什么建议吗?非常感激。
答案 0 :(得分:1)
在SQL Server 2005及更高版本中,“common table expression”可以执行此操作...
-- Assuming this table structure
--CREATE TABLE dbo.Test ( ID char(3), Type char(1), ParentID char(3))
;
WITH Tree(StartID, StartType, Parent, Child) AS
(
SELECT ID, Type, cast(NULL as char(3)), ID
FROM Test
WHERE ParentID IS NULL
UNION ALL
SELECT
-- Skip over the "X" rows...
CASE WHEN Tree.StartType = 'X'
THEN Test.ID
ELSE Tree.StartID
END,
CASE WHEN Tree.StartType = 'X'
THEN Test.Type
ELSE Tree.StartType
END,
Test.ParentID,
Test.ID
FROM Test
INNER JOIN Tree
ON Test.ParentID = Tree.Child
)
SELECT Test.ID, Test.Type, Test.ParentID,
CASE WHEN Tree.StartID = Test.ID
THEN NULL
ELSE Tree.StartID
END AS MasterParentID
FROM Test
LEFT OUTER JOIN Tree
ON Test.ID = Tree.Child
ORDER BY Test.ID
答案 1 :(得分:1)
以下是使用CTE实现该问题的查询,也是working demo
;with Childs as
(
select ID, Type, ParentID, 0 Level
from SomeHierarchy
union all
select Childs.ID, SomeHierarchy.Type, SomeHierarchy.ParentID, Childs.Level + 1 Level
from
SomeHierarchy
inner join Childs on Childs.ParentID = SomeHierarchy.ID
where
SomeHierarchy.Type not in ('R', 'X')
)
select
SomeHierarchy.ID, SomeHierarchy.Type, SomeHierarchy.ParentID, NewChilds.ParentID MasterParentID
from SomeHierarchy
inner join (
select *, Row_Number() over(Partition by ID order by Level desc) RowNum
from Childs
where
ParentID is not null or Level = 0
) NewChilds on NewChilds.ID = SomeHierarchy.ID
where
NewChilds.RowNum = 1
答案 2 :(得分:1)
你需要递归CTE:
with cte1 as (
select
T.ID, T.Type, T.ParentID,
case
when T2.Type = 'X' then cast(null as varchar(3))
else T.ParentID
end as MasterParentID
from Table1 as T
left outer join Table1 as T2 on T2.ID = T.ParentID
), cte2 as (
select
T.ID, T.Type, T.ParentID,
T.MasterParentID, T.ID as MasterParentID2
from cte1 as T
where T.MasterParentID is null
union all
select
T.ID, T.Type, T.ParentID,
c.MasterParentID2 as MAsterParentID,
c.MasterParentID2 as MAsterParentID2
from cte1 as T
inner join cte2 as c on c.ID = T.MasterParentID
)
select
T.ID, T.Type, T.ParentID, T.MasterParentID
from cte2 as T
order by ID asc