0

ジョブをリンクするテーブルがあります。

JobToJob
(
   JobToJobId int 
   SourceJobId int
   DestinationJobId int 
)

ジョブは複数の宛先ジョブ (つまり、複数の JobToJob レコード) を持つことができますが、ソース ジョブは 1 つだけです。したがって、これによりツリー構造が作成されます。ルート レコードは、他のレコードに DestinationJobId エントリがないものとして定義されます。

私が持っている要件は、提供されたジョブ ID のツリー全体を取得することです。これを 2 つの部分に分けました。

  1. 特定のジョブ ID のルート ジョブを見つける
  2. ルート ジョブ ID のすべてのリーフを取得します。

再帰的な CTE を使用してこれを試してみましたが、どこにも行きません。おそらくストアドプロシージャを使用してこれを行うことができることは承知していますが、処理が遅くなる傾向があるため、それを避けようとしています。

これにアプローチする最善の方法について、私よりも再帰的な CTE の経験がある人はいますか?

乾杯、

ロブ

4

2 に答える 2

0

Jobs テーブルがあることを願っています。

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 に答える
0

「リーフ」という用語を使用します。これは、(ツリー内の中間ノードではなく) 宛先のないジョブを意味します。

ここに 1 つのアプローチがあります。すべての葉から始めて、木に登り、それらが下にあるすべてのノードを取り付けます。次に、興味のある仕事に属するものを選択します。

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 に答える