Рекурсивный родительский / дочерний элемент в том же табличном запросе в SQL, где родительским элементом является PK - PullRequest
1 голос
/ 07 февраля 2020

Я видел много примеров того, как реализовать рекурсивный запрос, где родитель и потомок находятся в одной и той же таблице, но в примерах у потомка есть родитель, а мне наоборот, когда родитель есть ребенок Я хотел бы получить всех детей в рекурсивном режиме, как на картинке. Expected results

На изображении вы видите, у меня есть родитель с идентификатором 1, у него есть ребенок с идентификатором 2. Ребенок 2 также является родителем, у которого есть ребенок. с идентификатором 3 и т. д. c. Я не знаю, как создать рекурсивный запрос, чтобы получить все дочерние элементы от родителя. Вы можете получить доступ к следующей ссылке для выполнения sql онлайн: http://www.sqlfiddle.com/#! 18 / dbed2 / 1

Ответы [ 3 ]

1 голос
/ 07 февраля 2020

Здесь вы go:

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 Скрипка .

1 голос
/ 08 февраля 2020

если вы используете 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
1 голос
/ 07 февраля 2020

В результате вы получите запрошенные результаты:

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;

Здесь - это SQL Fiddle.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...