0

我有一张将工作链接在一起的表格:

JobToJob
(
   JobToJobId int 
   SourceJobId int
   DestinationJobId int 
)

一个 Job 可以有多个 Destination Jobs(即多于 1 个 JobToJob 记录),但只有 1 个源 Job。所以这创建了一个树结构。根记录定义为在任何其他记录上没有 DestinationJobId 条目的记录。

我的要求是检索提供的作业 ID 的整个树。我把它分成两部分:

  1. 找到给定作业 ID 的根作业
  2. 检索根作业 ID 的所有叶子。

我曾尝试使用递归 CTE 进行此操作,但我没有得到任何结果。我知道我可能可以通过使用存储过程来做到这一点,但我试图避免这样做,因为它们往往会减慢速度。

有没有比我有更多递归 CTE 经验的人对解决这个问题的最佳方法有任何建议?

干杯,

4

2 回答 2

0

您使用术语“离开”,这意味着没有目的地的作业(与树中的中间节点相反)。

这是一种方法。从所有叶子开始,然后爬上树,连接它们所在的所有节点。然后选择属于您感兴趣的工作的那些:

with cte as (
      select DestinationJobId as JobId, DestinationJobId as parent, 1 as level
      from jobs2jobs jj
      where DestinationJobId not in (select SourceJobId from jobs2jobs)
      union all
      select cte.JobId, jj.SourceJobId, level + 1
      from cte
           jobs2jobs jj
           on cte.Parent = jj.DestinationJobId
    )
select *
from cte
where parent = @YourJobId;
于 2013-09-13T15:42:38.397 回答
0

希望你有一个工作表。

declare @JobId int
;with getAscendants( job, parent, inverseDepth)
as
(
  select jj.DestinationJobId, jj.SourceJobId, 1
  from JobToJob jj 
  where jj.DestinationJobId = @JobId

  union all

  select jj.DestinationJobId, jj.SourceJobId, inverseDepth + 1
  from getAscendants
  join JobToJob jj on jj.DestinationJobId = getAscendants.parent
)
,rootFinder( job)
as
(
  select j.JobId
  from Jobs j
  where j.JobId = coalesce
  (
    (
      select top 1 parent from getAscendants order by inverseDepth desc
    )
    , @JobId
  )
)
,getDescendants( job, parent)
as
(
  select j.JobId, null
  from Jobs j
  cross apply rootFinder 
  where j.JobId = rootFinder.job

  union all

  select jj.DestinationJobId, jj.SourceJobId 
  from getDescendants
  join JobToJob jj on jj.SourceJobId = getDescendants.job
) 
select * from getDescendants
于 2013-09-13T16:18:07.620 回答