【问题标题】:Recursive Parent/Child in same table query in SQL where parent is PK父为PK的SQL中同一表查询中的递归父/子
【发布时间】:2020-05-23 23:45:40
【问题描述】:

我看过很多关于如何实现递归查询的示例,其中在同一个表中有父项和子项,但在示例中,子项有父项,而我需要相反,当父项有一个孩子。 我想以递归模式获得所有孩子,就像在图像中一样。

在图片中,你可以看到,我有一个 id 为 1 的父母,它有一个 id 为 2 的孩子。孩子 2 也是一个父母,他有一个 id 为 3 的孩子,等等。 我不知道如何创建递归查询以从父级获取所有子级。 可以访问下一个链接在线执行sql:http://www.sqlfiddle.com/#!18/dbed2/1

【问题讨论】:

  • 这可能是您在教科书中找到的第一个递归 CTE 示例。只需谷歌它,你就会找到很好的例子。
  • 感谢穿刺者。我找到了很多例子,但在这种情况下,孩子总是主键,父母可以有很多孩子。我有一个只有一个孩子的父母和一个有一个孩子的孩子,等等。

标签: sql sql-server recursion parent-child


【解决方案1】:

如果您使用的是 SQL Server 2017 或更高版本,则可以使用以下版本:

WITH CTE
AS (SELECT *
    FROM dbo.Table_1
    UNION ALL
    SELECT Child.idParent,
           Parent.idChild
    FROM CTE AS Parent
        INNER JOIN dbo.Table_1 AS Child
            ON Parent.idParent = Child.idChild)
SELECT CTE.idParent,
       STRING_AGG(CTE.idChild, ', ') AS Childs
FROM CTE
GROUP BY CTE.idParent;

但如果您有旧版本,请使用以下:

WITH CTE
AS (SELECT *
    FROM dbo.Table_1
    UNION ALL
    SELECT Child.idParent,
           Parent.idChild
    FROM CTE AS Parent
        INNER JOIN dbo.Table_1 AS Child
            ON Parent.idParent = Child.idChild)
SELECT DISTINCT
       B.idParent,
       STUFF(
       (
           SELECT ',' + CONVERT(VARCHAR(10), CTE.idChild)
           FROM CTE
           WHERE B.idParent = CTE.idParent
           ORDER BY CTE.idChild
           FOR XML PATH('')
       ),
       1,
       1,
       ''
            ) AS Childs
FROM CTE AS B

【讨论】:

    【解决方案2】:

    给你:

    with
    n as (
      select idparent, idchild, 1 as lvl, 
        cast(concat('', idchild) as varchar(255)) as children from family
    union all
      select n.idparent, f.idchild, lvl + 1, 
        cast(concat(children, ',', f.idchild) as varchar(255))
      from n
      join family f on f.idparent = n.idchild
    )
    select n.idparent, f.idchild, n.children
    from n
    join (
      select idparent, max(lvl) as maxlvl from n group by idparent
    ) m on n.idparent = m.idparent and n.lvl = m.maxlvl
    join family f on f.idparent = n.idparent
    order by n.idparent
    

    SQL Fiddle

    【讨论】:

      【解决方案3】:

      这会产生您要求的结果:

      with cte as (
            select idchild, idparent,
                   convert(varchar(max), idchild) as children
            from family f
            where not exists (select 1 from family f2 where f2.idparent = f.idchild)
            union all
            select f.idchild, f.idparent,
                   concat(f.idchild, ',', cte.children)
            from cte join
                 family f
                 on cte.idparent = f.idchild
           )
       select *
       from cte
       order by idchild;
      

      Here 是 SQL Fiddle。

      【讨论】:

      • 非常感谢,你真棒!
      猜你喜欢
      • 1970-01-01
      • 2016-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多