Table1有一个项目列表。 表2列出了与项目相关联的组。 表3是1和2之间的交叉引用。
表2中的组以分层方式设置。
Key ParentKey Name
1 NULL TopGroup1
2 NULL TopGroup2
3 1 MiddleGroup1
4 2 MiddleGroup2
5 3 NextGroup1
6 4 NextGroup1
7 2 MiddleGroup3
我希望能够从Table3中选择Table1 从Table1中选择项目Table3.ParentKey NOT'2'或其任何后代。
从另一篇文章here on stackoverflow我已经能够使用CTE来识别层次结构。
WITH Parent AS
(
SELECT
table2.Key,
cast(table2.Key as varchar(128)) AS Path
FROM
table2
WHERE
table2.ParentKey IS NULL
UNION ALL
SELECT
TH.Key,
CONVERT(varchar(128), Parent.Path + ',' + CONVERT(varchar(128),TH.Key)) AS Path
FROM
table2 TH
INNER JOIN
Parent
ON
Parent.Key = TH.ParentKey
)
SELECT * FROM Parent
我想这实际上是一个两部分问题。
答案 0 :(得分:2)
有关于此主题的整本书,请参阅:“Joe Celko's Trees and Hierarchies in SQL for Smarties”
就个人而言,当我不得不解决这个问题时,我使用了临时表来展开层次结构,然后从临时表中选择了一些东西。基本上,您可以在单个查询中在临时表中构建另一个层,通常层次结构只有5到10层深,因此您可以在5到10个查询中展开它。
答案 1 :(得分:1)
试试这个
-- Table1 (ItemKey as PK, rest of the columns)
-- Table2 (as you defined with Key as PK)
-- Table3 (ItemKey as FK referencing Table1(ItemKey),
-- GroupKey as FK referencing Table2(Key))
Declare @Exclude int
Set @Exclude = 2
;WITH Groups AS -- returns keys of groups where key is not equal
( -- to @Exclude or any of his descendants
SELECT t.Key
FROM table2 t
WHERE t.ParentKey IS NULL
and t.Key <> @Exclude
UNION ALL
SELECT th.Key,
FROM table2 th
INNER JOIN Groups g ON g.Key = th.ParentKey
Where th.Key <> @Exclude
)
SELECT t1.*
FROM Table1 t1
WHERE t1.key in (Select t3.ItemKey
From table3 t3
Inner Join Groups g2
on t3.GroupKey = g2.Key
)