Questo non è stato testato perché non ho un'installazione di mssql qui né i tuoi dati, ma penso che dovrebbe essere generalmente corretto e almeno spingerti in una direzione utile.
Innanzitutto, devi modificare la query nella tua UDF per fornire due ulteriori informazioni. L'impiegato "più in alto" per la tua aggregazione che sta crollando (che penso tu abbia detto è il primo dipendente diretto, non il più alto impiegato) e la profondità complessiva. In quanto tale:
WITH yourcte AS
(
SELECT EmployeeId, ManagerNTID, ManagerID, NTID, FullName, 0 as Depth, ntid as Topmost
FROM Employees
WHERE NTID = @NTID
UNION ALL
SELECT e.EmployeeId, e.ManagerNTID, e.ManagerID, e.NTID, e.FullName, y.Depth+1, case when y.depth = 0 then e.ntid else y.Topmost end
FROM Employees e
JOIN yourcte y ON e.ManagerNTID = y.NTID
)
SELECT EmployeeId, ManagerID, NTID, FullName, Depth, Topmost
FROM yourcte
Quindi, la tua query effettiva ha bisogno di alcuni dettagli extra per estrarre tali informazioni e utilizzarle
SELECT
e.FullName,
Urgent,
High,
Medium,
Low
FROM fnGetEmployeeHierarchyByUsername ('ssalvati') e
LEFT OUTER JOIN(
SELECT [AssignedTo],
SUM([1-Urgent]) AS Urgent,
SUM([2-High]) AS High,
SUM([3-Medium]) AS Medium,
SUM([4-Low]) AS Low
FROM (SELECT [AssignedTo],[BusinessSeverity] FROM Defects WHERE Status <> 'Closed') D
join fnGetEmployeeHierarchyByUsername ('ssalvati') e2 on d.AssignedTo = e2.ntid
PIVOT (COUNT([BusinessSeverity]) FOR [BusinessSeverity] IN ([1-Urgent],[2-High],[3-Medium],[4-Low])) V
where e2.TopMost = e.ntid
GROUP BY [AssignedTo]) AS def
ON e.ntid = def.[AssignedTo]
where e.Depth <= 1
La doppia chiamata alla tua UDF potrebbe essere un po' costosa, quindi potresti prendere in considerazione l'idea di inserirla in uno sproc e utilizzare una tabella temporanea per catturare i risultati dell'UDF a cui partecipare.
Tieni inoltre presente che l'UDF potrebbe richiedere un parametro aggiuntivo su quanto sia profondo "più in alto", rendendo più generale il fatto che attualmente sia nella sua forma hardcoded.