Вы возвращаете ParentID как GrandParent в вашем рекурсивном CTE.Это меняется, когда вы присоединяетесь к CTE, чтобы получить все уровни.
Если вы определите также поле GrandParentID на верхнем уровне и обратитесь к нему на втором уровне CTE, выполучите ответ:
with data1 as(
SELECT 1 [ModuleId], 'Master' [ModuleName], NULL [ParentId]
UNION ALL SELECT 2, 'UsersGroup2', 1
UNION ALL SELECT 3, 'UsersGroup3', 2
UNION ALL SELECT 4, 'UsersGroup4', 3
UNION ALL SELECT 5, 'UsersGroup5', 4
UNION ALL SELECT 6, 'UsersGroup6', 5
UNION ALL SELECT 7, 'UsersGroup7', 5
UNION ALL SELECT 8, 'UsersGroup8', NULL
UNION ALL SELECT 9, 'UsersGroup9', NULL
UNION ALL SELECT 10, 'UsersGroup10', 9
UNION ALL SELECT 11, 'UsersGroup11', 10
UNION ALL SELECT 12, 'UsersGroup12', 11
UNION ALL SELECT 14, 'UsersGroup14', 12
UNION ALL SELECT 15, 'UsersGroup15', 9
)
, CTE AS (SELECT 1 AS [Level], [ModuleId], [ModuleId] GrandParentID ,
[ModuleName] AS [GrandParent], [ModuleName], [ParentId]
FROM data1
WHERE [ParentId] IS NULL
UNION ALL
SELECT cycle.[Level] + 1,
base.[ModuleId],
cycle.GrandParentID,
cycle.[GrandParent],
base.[ModuleName],
base.[ParentId]
FROM data1 base
INNER JOIN CTE cycle ON cycle.[ModuleId] = base.[ParentId])
SELECT CTE.ModuleId, GrandParentId,COALESCE(NULLIF([GrandParent],[ModuleName])+'-->'+[ModuleName],[ModuleName]) AS [ModuleName]
FROM CTE
или в вашем формате:
WITH CTE AS (SELECT 1 AS [Level], [ModuleId], [ModuleId] GrandParentID,
[ModuleName] AS [GrandParent], [ModuleName], [ParentId]
FROM #Modules
WHERE [ParentId] IS NULL
UNION ALL SELECT cycle.[Level] + 1, base.[ModuleId],
cycle.[GrandParent], base.[ModuleName], base.[ParentId]
FROM #Modules base
INNER JOIN CTE cycle ON cycle.[ModuleId] = base.[ParentId])
SELECT CTE.ModuleId, CTE.GrandParentId, COALESCE(NULLIF([GrandParent],[ModuleName])+'-->'+[ModuleName],[ModuleName]) AS [ModuleName]
FROM CTE