SQL Server CTE -Найти верхний идентификатор родителя для каждого дочернего идентификатора?

У меня есть таблица, содержащая данные иерархии -что-то вроде:

childID  |  parentID
____________________
  1      |     5
  5      |     9
  9      |     20
  2      |     4
  3      |     7
  7      |     8
  8      |     8
 20      |     20
  4      |     4
  8      |     8

желаемый результат:

enter image description here

Я создал рекурсивный CTE, который находит меня наверху fatherID.

Что-то вроде:

;WITH cte AS (
                 SELECT a.childID
                      ,a.parentID
                      ,1 AS lvl
                 FROM   [Agent_Agents] a
                 WHERE   a.childID = 214 //<==== value to begin with !! - thats part the problem
                 UNION ALL
                 SELECT tmp.childID
                      ,tmp.parentID
                      ,cte.lvl+1
                 FROM   [Agent_Agents] tmp
                         INNER JOIN cte  ON  tmp.childID = cte.parentID
                 WHERE   cte.childID<>cte.parentID
             )
SELECT *
FROM   cte
WHERE   lvl = (
            SELECT MAX(lvl)
            FROM   cte
        )

Проблема:

Я выполнил CTE с явнымchildIDзначением, чтобы начать с (214 )! Так что это дает мне значение только для 214. CTE выполняет рекурсивную часть и находит topParent для childID.

но Я хочу, чтобыForEach row in the Table-выполнял CTE со значением childID!

Я пытался сделать это с помощьюCROSS APPLY:

Что-то вроде :

select * from myTable Cross Apply (
                                     ;WITH cte AS (....)
                                  )

, но ИМХО (из моего тестирования !!)-Это невозможно.

Другая идея помещения рекурсивного CTE в UDF имеет снижение производительности (проблемы udf, как мы знаем ).

Как создать этот запрос, чтобы он действительно работал? (или какое-то близкое решение )?

вот что я пробовал

https://data.stackexchange.com/stackoverflow/query/edit/69458

16
задан Cœur 29 August 2017 в 13:03
поделиться