帐户层次结构?父帐户有子女可以成为父母的子女

时间:2012-08-09 18:55:59

标签: sql sql-server-2008 hierarchy

我有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)

1 个答案:

答案 0 :(得分:0)

问题似乎是无法确定如何确定孩子是否有孩子以及孩子缺乏身份。如果CTE中的ON子句可以阻止子进入自身,那么它将破坏无限递归链。

示例输出和评论的答案应清楚表明您是否只需要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