Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

função sql recursiva com lógica de rollup?


Isso não é testado, pois não tenho uma instalação do mssql aqui nem seus dados, mas acho que deve estar geralmente certo e pelo menos empurrá-lo em uma direção útil.

Primeiro, você precisa alterar a consulta em sua UDF para fornecer duas informações adicionais. O funcionário "mais alto" para o colapso da sua agregação (que acho que você disse que é o primeiro subordinado direto, não o funcionário mais alto) e a profundidade geral. Como tal:
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

Então, sua consulta real precisa de alguns detalhes extras para extrair essas informações e usá-las
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

A chamada dupla para sua UDF pode ser um pouco cara, então você pode considerar colocar isso em um sproc e usar uma tabela temporária para capturar os resultados da UDF para unir.

Observe também que a UDF pode receber um parâmetro extra sobre o quão profundo é o "topmost", tornando isso mais geral do que atualmente está em sua forma codificada.