0

我有 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子句中的另一个条件或 aUNION来处理孩子的孩子。

这至少通过限制层次结构级别来停止递归,并提供一个任何人都可以执行而不会弄乱他们的数据库的测试平台:

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 回答