0

私は2つのテーブルを持っています。1 つのテーブルには、階層の最上位にあるすべての親勘定が含まれます。2 番目のテーブルにはすべての子アカウントがあり、親テーブルの親アカウントと一致する場合と一致しない場合があります。目標は、親に一致するすべての子アカウントを検索するクエリ (SQL Server 2008、再帰的または非再帰的) を作成することです。さらに、子はそれ自体が他の子アカウントの親になる可能性があります。

簡単に言えば、親から子への一致が確立されたら、一致した子がそれ自体が他の子アカウントの親ではないことを確認する必要があります。一口私は理解しており、それが理にかなっていることを願っています. また、ヒエラルキーがどの深さまで拡張されるかもわかりません。

CREATE TABLE dbo.Parent_Accounts
(Parent_Account_Key_Lookup     varchar(28)          NOT NULL,
 Account_Number            bigint       NOT NULL,
 Reference_Account_Number_1        bigint       NOT NULL,
 Reference_Account_Number_2        bigint       NOT NULL,
 OpenDate              int          NOT NULL,
 Status                        char(1)              NOT NULL,
 Record_Created            smalldatetime    NOT NULL,
 Active                bit          NOT NULL)
GO

CREATE TABLE dbo.Child_Accounts
(Child_Account_Key_Lookup      varchar(28)          NOT NULL,
 Account_Number            bigint       NOT NULL,
 Reference_Account_Number_1        bigint       NOT NULL,
 Reference_Account_Number_2        bigint       NOT NULL,
 OpenDate              int          NOT NULL,
 Status                        char(1)              NOT NULL,
 Record_Created            smalldatetime    NOT NULL,
 Active                bit          NOT NULL)
GO

    WITH cte_Recursive
AS  (SELECT parent.Account_Number,
        parent.Parent_Account_Key_Lookup,
        parent.Reference_Account_Number_1,
        parent.Reference_Account_Number_2,
        parent.OpenDate,
        parent.[Status],
        parent.Record_Created,
        parent.Active,
        1 AS Hierarchy_Level
     FROM dbo.Parent_Accounts parent
     WHERE parent.Account_Number = 4498481055218674
     UNION ALL
     SELECT child.Account_Number,
        child.Child_Account_Key_Lookup,
        child.Reference_Account_Number_1,
        child.Reference_Account_Number_2,
        child.OpenDate,
        child.[Status],
        child.Record_Created,
        child.Active,
        cte.Hierarchy_Level + 1
     FROM cte_Recursive cte
     INNER JOIN dbo.Child_Accounts child
         ON cte.Parent_Account_Key_Lookup = child.Child_Account_Key_Lookup)

    --SELECT * FROM cte_Recursive
            SELECT TOP 2 * FROM cte_Recursive

INSERT INTO dbo.Parent_Accounts
 (Parent_Account_Key_Lookup, 
  Account_Number, 
  Reference_Account_Number_1, 
  Reference_Account_Number_2, 
  OpenDate, 
  [Status], 
  Record_Created, 
  Active)
 VALUES ('222248105521867419970702', 2222481055218674, 2222481060975466, 0, 19970702, 'U', '2010-11-18 12:46:00', 0)

 INSERT INTO dbo.Child_Accounts
 (Child_Account_Key_Lookup, 
  Account_Number, 
  Reference_Account_Number_1, 
  Reference_Account_Number_2, 
  OpenDate, 
  [Status], 
  Record_Created, 
  Active)
 VALUES ('222248105521867419970702', 2222481060975466, 2222481055218674, 2222481055218674, 19970702, 'L', '2010-11-19 08:33:00', 0),
    ('222248106097546619970702', 2222481060982900, 2222481060989137, 2222481060975466, 19970702, 'U', '2010-11-19 16:54:00', 0),
    ('222248106098290019970702', 2222481060989137, 0,                2222481060982900, 19970702, ' ', '2010-11-21 01:52:00', 1)
4

1 に答える 1

0

問題は、子供が子供を持っていることを特定する方法を指定できないことと、子供のアイデンティティの欠如にあるようです。ONCTEの句が子がそれ自体に結合するのを防ぐことができる場合、無限再帰チェーンが壊れます。

ONサンプル出力とコメントへの回答により、節に別の条件が必要なのか、UNION子の子を処理する必要があるのか​​が明確になります。

これにより、少なくとも階層レベルを制限することで再帰を停止し、データベースを乱雑にすることなく誰でも実行できるテストベッドを提供します。

declare @Parent_Accounts as table (
  Parent_Account_Key_Lookup varchar(28) NOT NULL, 
  Account_Number bigint NOT NULL, 
  Reference_Account_Number_1 bigint NOT NULL, 
  Reference_Account_Number_2 bigint NOT NULL, 
  OpenDate int NOT NULL, 
  Status char(1) NOT NULL, 
  Record_Created smalldatetime NOT NULL, 
  Active bit NOT NULL) 

declare @Child_Accounts as table (
  Child_Account_Key_Lookup varchar(28) NOT NULL, 
  Account_Number bigint NOT NULL, 
  Reference_Account_Number_1 bigint NOT NULL, 
  Reference_Account_Number_2 bigint NOT NULL, 
  OpenDate int NOT NULL, 
  Status char(1) NOT NULL, 
  Record_Created smalldatetime NOT NULL, 
  Active bit NOT NULL) 

INSERT INTO @Parent_Accounts 
  (Parent_Account_Key_Lookup, Account_Number, Reference_Account_Number_1, Reference_Account_Number_2, OpenDate, [Status], Record_Created, Active) VALUES
  ('222248105521867419970702', 2222481055218674, 2222481060975466, 0, 19970702, 'U', '2010-11-18 12:46:00', 0) 

 INSERT INTO @Child_Accounts 
  (Child_Account_Key_Lookup, Account_Number, Reference_Account_Number_1, Reference_Account_Number_2, OpenDate, [Status], Record_Created, Active) VALUES
  ('222248105521867419970702', 2222481060975466, 2222481055218674, 2222481055218674, 19970702, 'L', '2010-11-19 08:33:00', 0), 
  ('222248106097546619970702', 2222481060982900, 2222481060989137, 2222481060975466, 19970702, 'U', '2010-11-19 16:54:00', 0), 
  ('222248106098290019970702', 2222481060989137, 0, 2222481060982900, 19970702, ' ', '2010-11-21 01:52:00', 1) 

; WITH cte_Recursive 
AS (SELECT parent.Account_Number, 
 parent.Parent_Account_Key_Lookup, 
 parent.Reference_Account_Number_1, 
 parent.Reference_Account_Number_2, 
 parent.OpenDate, 
 parent.[Status], 
 parent.Record_Created, 
 parent.Active, 
 1 AS Hierarchy_Level 
 FROM @Parent_Accounts parent 
 WHERE parent.Account_Number = 2222481055218674 
 UNION ALL 
 SELECT child.Account_Number, 
 child.Child_Account_Key_Lookup, 
 child.Reference_Account_Number_1, 
 child.Reference_Account_Number_2, 
 child.OpenDate, 
 child.[Status], 
 child.Record_Created, 
 child.Active, 
 cte.Hierarchy_Level + 1 
 FROM cte_Recursive cte 
 INNER JOIN @Child_Accounts child 
 ON cte.Parent_Account_Key_Lookup = child.Child_Account_Key_Lookup and cte.Hierarchy_Level < 2) 
 SELECT * FROM cte_Recursive 
于 2012-08-09T20:51:41.920 に答える