Aquí hay uno que funciona para mí:
@ParentID es solo un punto de partida en la jerarquía, pero puede pasar 0 (pero creo que está usando nulo como ID base, por lo que entenderá la idea)
La clave para la clasificación ordenada está en la clave de clasificación que se crea.
WITH RoleHierarchy (RoleID, [Role], [Description], ParentID, Editable, HierarchyLevel, SortKey) AS
(
-- Base
SELECT
RoleID,
[Role],
[Description],
ParentID,
Editable,
0 as HierarchyLevel,
CAST(RoleID AS VARBINARY(300))
FROM
dbo.Roles
WHERE
RoleID = @ParentID
UNION ALL
-- Recursive
SELECT
e.RoleID,
e.[Role],
e.[Description],
e.ParentID,
e.Editable,
th.HierarchyLevel + 1 AS HierarchyLevel,
CAST (th.SortKey + CAST (e.[Role] AS VARBINARY(100)) + CAST (e.[RoleID] AS VARBINARY(100)) AS VARBINARY(300))
FROM
Roles e
INNER JOIN RoleHierarchy th ON e.ParentID = th.RoleID
WHERE
e.RoleID != 0
)
SELECT
RoleID,
ParentID,
[Role],
[Description],
Editable,
HierarchyLevel
FROM
RoleHierarchy
WHERE
RoleID != @ParentID
ORDER BY
SortKey