2012-06-05 2 views
1

У меня есть таблица (см. Изображение) Сотрудники (менеджер - менеджер другого и т. Д.) С id, parentid, зарплата, totalsalary. Последнее необходимо обновить, чтобы каждый сотрудник имел сумму окладов своих потомков. Я уже написал скрипт, который получает общую зарплату по идентификатору и столбцу обновлений в курсоре, но он тяжелый ... любые другие способы?Обновление таблицы таблиц по рекурсии

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 ; 

this is my test table of Employees

+1

Прокомментируйте вашу версию SQL Server – njr101

ответ

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 
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 столбец вычисляемого столбца с помощью функции:

dbo.fn_TotalSalary(EmployeeId) 

Как сотрудники зарабатывают больше, вычисляемый столбец будет обновляться автоматически. Затем вы можете просто позвонить:

select * from Employees 

Чтобы получить подробную информацию. Выполнение этого способа будет означать, что ваши данные всегда на 100% точны и обновлены, а не могут извлекать устаревшие данные.

Смежные вопросы