i have a SQL that using a recursive CTE to expand a self-referancing employees table builds a result set of defects aggregated by user and severity level.
here is my CTE
This isn't tested as I don't have a mssql install here nor your data, but, I think it should be generally right and at least push you in a useful direction.
First, you need to change the query in your UDF to give two additional pieces of information. The "topmost" employee for your aggregation collapsing (which I think you said is the first direct report, not the very top employee), and the overall depth. As such:
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
Then, your actual query needs a few extra details to extract that information and use it
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
The double call to your UDF might be a bit expensive, so you may want to consider putting this into a sproc and using a temp table to catch the results of the UDF to join against.
Also note that the UDF could take an extra parameter as to how deep "topmost" is, making this more general that it currently is in its hardcoded form.