Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

funzione SQL ricorsiva con logica di rollup?

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.