如何在sql中查找单个查询中的子节点列表

Nee*_*dav 4 sql sql-server stored-procedures

嗨,我在桌子下面.

Create table ParentChildhierarchy (Parent varchar(50),Child varchar(50))
Run Code Online (Sandbox Code Playgroud)

在这个表中,我使用下面的SQL脚本插入了几行.

insert into ParentChildhierarchy values('A','B')

insert into ParentChildhierarchy values('B','C')

insert into ParentChildhierarchy values('C','D')

insert into ParentChildhierarchy values('E','A')

insert into ParentChildhierarchy values('F','K')
Run Code Online (Sandbox Code Playgroud)

现在我需要一个单行查询,它可以给我所有子节点的列表.例如,对于父"A",它应该列出"B,C,D".对于父"B",它应该列出父母"C"的"C,D",它应该列出父母"D"的"D",它应该列出父"E"的"Null",它应该列出对于父母"F"下来"A",它应该列出"K"

Dee*_*war 6

使用递归查询:

DECLARE @Parent VARCHAR(50) = 'A'
;WITH cte
     AS (SELECT *
         FROM   ParentChildhierarchy
         WHERE  parent = @Parent 
         UNION ALL
         SELECT a.*
         FROM   ParentChildhierarchy a
                JOIN cte b
                  ON a.parent = b.child)
SELECT *
FROM   cte 
Run Code Online (Sandbox Code Playgroud)

更新:以下查询将结果结果:

DECLARE @Parent VARCHAR(50) = 'A'
;WITH cte
     AS (SELECT *
         FROM   ParentChildhierarchy
         WHERE  parent = @Parent 
         UNION ALL
         SELECT a.*
         FROM   ParentChildhierarchy a
                JOIN cte b
                  ON a.parent = b.child)
SELECT STUFF((SELECT ',' + Child
              FROM   cte
              FOR XML PATH('')), 1, 1, '') 
Run Code Online (Sandbox Code Playgroud)

SQLFiddle

更新2:

对于所有行:

;WITH cte
     AS (SELECT *,
                Parent [TopParent]
         FROM   ParentChildhierarchy
         --WHERE  Parent = 'A'
         UNION ALL
         SELECT a.*,
                [TopParent]
         FROM   ParentChildhierarchy a
                JOIN cte b
                  ON a.parent = b.child)
SELECT [TopParent],
       STUFF((SELECT ',' + Child
              FROM   cte b
              WHERE  a.[TopParent] = b.[TopParent]
              FOR XML PATH('')), 1, 1, '')
FROM   cte a
GROUP  BY [TopParent] 
Run Code Online (Sandbox Code Playgroud)

SQLFiddle

所有那些没有孩子的行:

;WITH cte
     AS (SELECT *,
                Parent [TopParent]
         FROM   ParentChildhierarchy
         --WHERE  Parent = 'A'
         UNION ALL
         SELECT a.*,
                [TopParent]
         FROM   ParentChildhierarchy a
                JOIN cte b
                  ON a.parent = b.child) SELECT [TopParent],
       STUFF((SELECT ',' + Child
              FROM   cte b
              WHERE  a.[TopParent] = b.[TopParent]
              FOR XML PATH('')), 1, 1, '')
FROM   cte a
GROUP  BY [TopParent]
UNION
SELECT Child,
       NULL
FROM   ParentChildhierarchy p
WHERE  NOT EXISTS (SELECT 1
                   FROM   ParentChildhierarchy c
                   WHERE  p.Child = c.Parent) 
Run Code Online (Sandbox Code Playgroud)

SQLFiddle

查看有关递归查询的Microsoft文档:https://technet.microsoft.com/en-us/library/ms186243(v = sql.105).aspx