1

私はテーブルを持っています(画像を参照)従業員(マネージャーは別のマネージャーなど)、id、parentid、salary、totalsalary。最後のものは、すべての従業員がその子孫の給与の合計を持つように更新する必要があります。IDごとに合計給与を取得し、カーソルの列を更新するスクリプトをすでに作成しましたが、重いです...他の方法はありますか?

DECLARE @id INT ;
DECLARE @s INT ;
DECLARE curs CURSOR FOR
SELECT personid FROM dbo.Employees
OPEN curs ;
FETCH NEXT FROM curs INTO @id ;
WHILE @@FETCH_STATUS = 0 
    BEGIN
        WITH    Xemps ( ID )
                  AS ( SELECT   PersonID AS ID
                       FROM     dbo.Employees
                       WHERE    PersonID = @id
                       UNION ALL
                       SELECT   e.PersonID AS ID
                       FROM     dbo.Employees AS e
                                INNER JOIN Xemps AS x ON e.ManagerID = x.ID
                     )
            SELECT  @s = SUM(Salary)
            FROM    dbo.Employees
            WHERE   PersonID IN ( SELECT    id
                                  FROM      Xemps )
        UPDATE  dbo.Employees
        SET     SalarySum = @s
        WHERE   PersonID = @id
        FETCH NEXT FROM curs INTO @id
    END
CLOSE curs ;
DEALLOCATE curs ;

これは私の従業員のテストテーブルです

4

2 に答える 2

4

カーソルは必要ありません。これは、再帰共通テーブル式を使用して実行できます。

WITH Emp AS
(   SELECT  EmployeeID, Salary, ManagerID
    FROM    dbo.Employee
    UNION ALL
    SELECT  e.EmployeeID, e.Salary, Emp.ManagerID
    FROM    dbo.Employee e
            INNER JOIN Emp
                ON e.ManagerID = Emp.EmployeeID
)
UPDATE  dbo.Employee
SET     SalarySum = COALESCE(s.Salary, 0) + e.Salary
FROM    dbo.Employee e
        LEFT JOIN 
        (   SELECT  ManagerID, SUM(Salary) [Salary]
            FROM    Emp
            GROUP BY ManagerID
        ) s
            ON s.ManagerID = e.EmployeeID
于 2012-06-05T12:26:27.750 に答える
1

マネージャーである各従業員の合計を実行する関数を作成します。

create function dbo.fn_TotalSalary    
{
  @EmployeeId int
} 
returns float
as
begin

  declare @totalSalary float

  select @totalSalary = sum(salary)
  from dbo.employees 
  where employeeid = @employeeid or managerid = @employeeid

  return @totalSalary 
end

次に、次の関数を使用して、TotalSalary列を計算列に変更し、Employeesテーブルを変更します。

dbo.fn_TotalSalary(EmployeeId)

従業員の収入が増えると、計算列は自動的に更新されます。その後、あなたは単に呼び出すことができます

select * from Employees

詳細を取得します。このようにすることは、古いデータを取得する可能性があるのではなく、データが常に100%正確で最新であることを意味します。

于 2012-06-05T12:52:30.550 に答える