Вы можете попробовать это:
DECLARE @mockup TABLE(Max_ID INT,Second_Max_ID INT);
INSERT INTO @mockup VALUES
(97 ,NULL )
,(173 , 97 )
,(174 , 173 )
,(175 , 174 );
WITH recCTE AS
(
SELECT Max_ID
,Second_Max_ID
,CAST(Max_ID AS VARCHAR(MAX)) AS Cumulative_ID
FROM @mockup WHERE Second_Max_ID IS NULL
UNION ALL
SELECT m.Max_ID
,m.Second_Max_ID
,CONCAT(r.Cumulative_ID,',',m.Max_ID)
FROM @mockup m
INNER JOIN recCTE r ON r.Max_ID=m.Second_Max_ID
)
SELECT * FROM recCTE;
Идея - рекурсивный CTE (скорее, итерационный подход).Вы начинаете с одной строки без parent (Second_Max_ID IS NULL
).
Это перемещается по списку (скрытый RBAR ) и выполняет конкатенацию на лету .
Вы отмечены v2008 и v2012.Если CONCAT()
не работает для вас, вы можете легко использовать простой +
с необходимым преобразованием в varchar
.
ОБНОВЛЕНИЕ
В этой версии я добавлю счетчик для глубины иерархии:
WITH recCTE AS
(
SELECT Max_ID
,Second_Max_ID
,CAST(Max_ID AS VARCHAR(MAX)) AS Cumulative_ID
,1 AS HierarchyLevel
FROM @mockup WHERE Second_Max_ID IS NULL
UNION ALL
SELECT m.Max_ID
,m.Second_Max_ID
,CONCAT(r.Cumulative_ID,',',m.Max_ID)
,r.HierarchyLevel+1
FROM @mockup m
INNER JOIN recCTE r ON r.Max_ID=m.Second_Max_ID
)
SELECT *
FROM recCTE;
Вы можете использовать
- a
WHERE
для фильтрации для специального уровня - TOP 1 в сочетании с
ORDER BY HierachyLevel DESC
для получения последнего элемента (с самым длинным путем).
Надеюсь, это поможет!