Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

rekursive SQL-Funktion mit Rollup-Logik?

Dies ist nicht getestet, da ich hier weder eine MSSQL-Installation noch Ihre Daten habe, aber ich denke, es sollte im Allgemeinen richtig sein und Sie zumindest in eine nützliche Richtung drängen.

Zunächst müssen Sie die Abfrage in Ihrem UDF ändern, um zwei zusätzliche Informationen bereitzustellen. Der "oberste" Mitarbeiter für Ihre Aggregation kollabiert (was Sie, glaube ich, als den ersten direkten Untergebenen bezeichnet haben, nicht den allerobersten Mitarbeiter) und die Gesamttiefe. Als solches:

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

Dann benötigt Ihre eigentliche Abfrage einige zusätzliche Details, um diese Informationen zu extrahieren und zu verwenden

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

Der doppelte Aufruf Ihrer UDF könnte ein bisschen teuer sein, also sollten Sie erwägen, dies in einen Sproc zu packen und eine temporäre Tabelle zu verwenden, um die Ergebnisse der UDF zu erfassen, gegen die Sie sich anschließen möchten.

Beachten Sie auch, dass die UDF einen zusätzlichen Parameter annehmen könnte, wie tief "topmost" ist, was dies allgemeiner macht, dass es derzeit in seiner fest codierten Form vorliegt.