所以我正在尝试编写一个递归查询来获取项目及其父项。问题是我的结构可以有很多父母,查询没有得到最后一行。结构是:
Entity
Id |
1 |
2 |
3 |
EntityMembership
ChildId | ParentId
3 | 2
2 | 1
到目前为止,查询看起来像:
with results(BaseId, Id, ParentId) as
(
select e.id as BaseId, e.id, em.parentid
from entity e
left join EntityMembership em on e.Id = em.ChildID
union all
select r.BaseId, e.id, em.parentid
from entity e
inner join EntityMembership em on e.Id = em.ChildID
inner join results r on r.parentid = e.id
where r.Id<> r.ParentId
)
select results.Id
from results
where BaseId = 3
出现如下:
3 |
2 |
显然内部联接阻止“1”出现在结果中,因为它没有父级,但我不知道如何重写它以包含它。
答案 0 :(得分:1)
问题是你在CTE的第二部分对EntityMembership进行了内部联接,所以你在结果中没有得到“1”。它应该是外连接(如第一部分中所示),但不允许在递归CTE中具有外连接。我的解决方案是提前在另一个CTE中加入Entity和EntityMembership,并在递归中使用它。
with joined(ChildId, ParentId) as
(select e.id, em.parentid
from entity e
left outer join entitymembership em on em.childid = e.id
),
results(BaseId, Id, ParentId) as
(
select j.ChildId as BaseId, j.ChildId, j.parentid
from joined j
union all
select r.BaseId, j.ChildId, j.parentid
from joined j
inner join results r on r.parentid = j.ChildId
where r.Id <> r.ParentId
)
select Id
from results
where BaseId = 3
这是一种稍微不同的编写方式,过滤CTE中的子Id,而不是之后:
with joined(ChildId, ParentId) as
(select e.id, em.parentid
from entity e
left outer join entitymembership em on em.childid = e.id
)
,results(ChildId, ParentId) as
(
select j.childid, j.parentid
from joined j
where j.childid = 3
union all
select j.childid, j.parentid
from joined j
join results r on r.parentid = j.childid
)
select ChildId
from results