2016-05-30 10 views
2

私は多くのテーブル依存関係を持っていますが、これには2つの列SourceIdとDependsOnIdがあります。私は本当に与えられたIDのすべての扶養家族を再帰的に取得したいと思う。今のCTE再帰的クエリループ

私は次のクエリがあります。

with Rec(SourceId, DependsOnId) 
as (
select SourceId, DependsOnId from [dbo].[Dependency] 
union all 
select Rec.SourceId, Rec.DependsOnId 
from [dbo].[Dependency] d 
join [dbo].[Dependency] dd 
on d.SourceId = dd.DependsOnId and d.DependsOnId = dd.SourceId 
join Rec 
on Rec.DependsOnId = d.SourceId 

) 
SELECT * FROM Rec 
OPTION (MAXRECURSION 30000); 

をしかし、それは無限ループに好みます。私はなぜそれが1> 2および2> 1のような鏡の依存関係のためにあるのか理解しています。だから私はこのようなケースを一度だけ処理する必要があります。

あなたのお手伝いをお待ちしております。

+0

いくつかのサンプル入力データを共有できますか? –

+1

あなたのデータにサイクルがある場合、私は感謝の意を表すCTEがあなたのためにうまく動作しないことになります。あなたは基本的に組合よりも別個のものを実行する必要があり、CTEがそれをサポートしているかどうかは分かりませんしかし:))。一時テーブルがうまくいくかもしれません。 – Luaan

+0

@Luaanありがとうございます。私は間違った方法で続いたことが分かった。私は一時的なテーブルを使用しようとします、あなたは正しい方向に私をプッシュすることができますか?なぜなら、とにかく再帰が必要なようですが、CTEはオプションではないと言いました。 –

答えて

0

Hmmm。ジョインがあまりにも多いと思う。これを試してください:

with Rec(SourceId, DependsOnId) as (
     select SourceId, DependsOnId 
     from [dbo].[Dependency] 
     union all 
     select Rec.SourceId, d.DependsOnId 
     from Rec join 
      [dbo].[Dependency] d 
      on Rec.DependsOnId = d.SourceId 
    ) 
SELECT * 
FROM Rec 
OPTION (MAXRECURSION 30000); 

サブクエリは、ループを通過するときに1つの深さに依存関係を追加します。

注:データにサイクルがある場合、これは無限再帰を持つことができます。これはあなたのために動作しない場合は、SQLフィドルを設定することをお勧めします。

+0

CTE呼び出しに対する複数の参照を使用することはできません。だからあなたはfuncがエラーである) –

+0

@IlyaLivshits。 。 。私は誤って答えのコード行を残しました。とにかく私はサイクルがあると言ったように、 –

+0

。だから解決策ではありません) –

0
DECLARE @ParentID INT = 2; 

WITH CTE AS(
     SELECT SourceId, DependsOnId 
     FROM [dbo].[Dependency] 
     WHERE SourceId = @ParentID --<-- Given Parent id 

     UNION ALL 

     SELECT t.SourceId, t.DependsOnId 
     FROM [dbo].[Dependency] t 
     INNER JOIN 
       CTE c ON t.DependsOnId = c.SourceId 
) 
SELECT * 
FROM CTE 
+0

残念ながら失敗しました(これは最初のレベルの扶養家族のみを返しますが、とにかくありがとう –