sql >> データベース >  >> RDS >> Sqlserver

ロールアップロジックを使用した再帰的SQL関数?

    私はここに mssql をインストールしておらず、データも持っていないため、これはテストされていませんが、一般的には正しく、少なくとも有用な方向に進むべきだと思います.

    まず、UDF のクエリを変更して、2 つの追加情報を提供する必要があります。集約が崩壊する「最上位」の従業員(これは、最上位の従業員ではなく、最初の直属の部下だと思います)、および全体的な深さ。

    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
    

    次に、実際のクエリには、その情報を抽出して使用するための追加の詳細がいくつか必要です

    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
    

    UDF への二重呼び出しは少しコストがかかる可能性があるため、これを sproc に入れ、一時テーブルを使用して結合対象の UDF の結果をキャッチすることを検討してください。

    また、UDF は「最上位」の深さに関する追加のパラメーターを取得できることに注意してください。これにより、現在はハードコードされた形式であることがより一般的になります。



    1. django 1.11.4のエラー('datetime.datetime'オブジェクトには属性'split'がありません)

    2. 最後に挿入されたレコードの ID を取得する

    3. Entity Framework 4 階層ごとのテーブル - 子のナビゲーション プロパティを定義する方法は?

    4. 初心者向けのSQLEquals(=)演算子