0

次の表を検討してください。

SELECT [ItemID]
      ,[ParentID]
      ,[PolicyID]
      ,[PolicyRoot]
  FROM [AdventureWorks2008R2].[dbo].[Example]


ItemID      ParentID    PolicyID   PolicyRoot
----------- ----------- ---------- ----------
1           NULL        default    1
2           1           b          1
3           1           c          0
4           NULL        d          1
5           3           e          0
6           3           f          1
7           NULL        g          0

から使用する必要がある場合に備えてPolicyID、各項目からを選択しようとしています。これは再帰的です...PolicyRoot = 1PolicyRoot = 0PolicyIDParentID

関数の操作:

CREATE FUNCTION dbo.Policies(@ItemID INT) RETURNS VARCHAR(10)
AS
BEGIN
    DECLARE @ParentID INT, @PolicyRoot BIT, @PolicyID VARCHAR(10)

    SELECT  @ParentID = ParentID
    ,       @PolicyRoot = PolicyRoot
    ,       @PolicyID = PolicyID
    FROM    [dbo].[Example]
    WHERE   ItemID = @ItemID

    IF      @PolicyRoot != 1
            SELECT @PolicyID = dbo.Policies(@ParentID)
    RETURN  @PolicyID
END;

GO

SELECT  ItemID
,       dbo.Policies(ItemID) AS Policy 
FROM    [dbo].[Example];


ItemID      Policy
----------- ----------
1           default
2           b
3           default
4           d
5           default
6           f
7           NULL

この関数を CTE に書き直そうとしていますが、まだ CTE の知識がありません。複数の CTE を読みましたが、条件付き CTE を管理する方法がまったくわかりません。これは私が得た限りであり、UNION ALL.

WITH Policies (ItemID, PolicyID) AS (
    SELECT  ItemID
    ,       PolicyID
    FROM    dbo.Example

    UNION ALL

    ...
)
SELECT  ItemID
,       PolicyID
FROM    Policies;

そのようなCTEがどのように機能するかを簡単な手順で説明し、正しい方向に私を押し進めることができますか?

4

1 に答える 1

2

再帰的な CTE はUNION ALL、結果を照合するために a を使用して、それ自体に結合することによって機能します。

テーブルから始めて、再帰クエリの初期データセットを設定します

    select * from yourtable

そしてUNION ALL、さらに結果を追加します

    select c.ItemID, t2.ParentID, t2.PolicyID, t2.PolicyRoot
    from yourtable t2
        inner join c on c.ParentID = t2.ItemID 
      where c.PolicyRoot=0

再帰はこれで発生します-このクエリの結果がこのクエリを何度も何度もフィードされ、MAXRECURSION制限まで、またはそれ以上の結果が追加されない場合。

;with c as 
(
    select * from yourtable
    union all
    select c.ItemID, t2.ParentID, t2.PolicyID, t2.PolicyRoot
    from yourtable t2
        inner join c on c.ParentID = t2.ItemID 
      where c.PolicyRoot=0
)
select t.ItemID, c.PolicyID 
      from yourtable t
     left join c on t.ItemID = c.ItemID 
                 and c.PolicyRoot=1
于 2013-09-12T12:05:03.067 に答える