我在SQL中有以下两个表。第一个表是ID,Parents和OwnerGroup的层次结构。第二个表是每个OwnerGroup中的成员集合。任务是在包含实际成员的层次结构中向上返回最近的OwnerGroup。
底部的SQL查询是我的查询的简化版本,它返回ID为1-4的正确成员,但对于ID 5和6,它返回一个空结果,因为MemberInOwnerGroup不包含OwnerGroup ='的值C'。在这种情况下,查询应继续遍历Product表并在OwnerGroup ='B'中获得结果。
任何帮助将不胜感激!
产品
------------------------------
| ID | ParentID | OwnerGroup |
------------------------------
| 1 | | A |
| 2 | 1 | |
| 3 | 2 | B |
| 4 | 3 | |
| 5 | 4 | C |
| 6 | 5 | |
------------------------------
MemberInOwnerGroup
-----------------------
| OwnerGroup | Member |
-----------------------
| A | Alice |
| A | Bob |
| B | Dan |
| C | |
-----------------------
返回会员的SQL查询
WITH Hierarchy(ID, ParentID, OwnerGroup, NearestOwnerGroup)
AS
(
SELECT ID, ParentID,OwnerGroup,CAST(OwnerGroup AS VARCHAR(MAX))
FROM Product
WHERE ParentID IS NULL
UNION ALL
SELECT NextGeneration.ID, NextGeneration.ParentID,NextGeneration.OwnerGroup,
CAST(CASE WHEN NextGeneration.OwnerGroup not like ''
THEN(CAST(NextGeneration.OwnerGroup AS VARCHAR(MAX)))
ELSE(Parent.NearestOwnerGroup)
END AS VARCHAR(MAX))
FROM Product AS NextGeneration
INNER JOIN Hierarchy AS Parent ON NextGeneration.ParentID = Parent.ID
)
SELECT Member FROM MemberInOwnerGroup WHERE OwnerGroup IN
(
SELECT Hierarchy.NearestOwnerGroup
FROM Hierarchy
WHERE Hierarchy.ID = '6'
)
不同ID的预期结果应为以下
--------------------
| ID | Member |
--------------------
| 1 | Alice, Bob |
| 2 | Alice, Bob |
| 3 | Dan |
| 4 | Dan |
| 4 | Dan |
| 6 | Dan |
--------------------
答案 0 :(得分:0)
我在MemberInOwnerGroup
表的联接中添加了返回组成员的表(如果为空,则返回ParentGroup)。这会在cte
中创建重复行,这些行由生成的where exists
语句中的select
处理。
根据数据集的大小,这可能会导致性能问题:
with Hierarchy as
(
select ID
,ParentID
,OwnerGroup
,cast(OwnerGroup as varchar(max)) as NearestOwnerGroup
from Product
where ParentID is null
union all
select NextGeneration.ID
,NextGeneration.ParentID
,NextGeneration.OwnerGroup
,cast(case when GroupMember.Member = '' then Parent.NearestOwnerGroup else GroupMember.OwnerGroup end as varchar(max)) as NearestOwnerGroup
from Product as NextGeneration
inner join Hierarchy as Parent
on NextGeneration.ParentID = Parent.ID
inner join (select OwnerGroup
,Member
from MemberInOwnerGroup
) GroupMember
on GroupMember.OwnerGroup = case when NextGeneration.OwnerGroup = '' then Parent.OwnerGroup else NextGeneration.OwnerGroup end
)
select m.Member
from MemberInOwnerGroup m
where exists (select null
from Hierarchy h
where h.NearestOwnerGroup = m.OwnerGroup
and h.ID = '6'
)