Tsql 通过递归更新管理器表树
我有一个员工表(见图)(经理是另一个的经理,以此类推),表中有id、parentid、salary、totalsalary。最后一个需要更新,以便每个员工都有自己的工资总额。我已经写了脚本,它通过id获取总工资,然后更新游标中的列,但它很重。。。还有别的办法吗Tsql 通过递归更新管理器表树,tsql,recursion,sql-server-2008-r2,sum,with-statement,Tsql,Recursion,Sql Server 2008 R2,Sum,With Statement,我有一个员工表(见图)(经理是另一个的经理,以此类推),表中有id、parentid、salary、totalsalary。最后一个需要更新,以便每个员工都有自己的工资总额。我已经写了脚本,它通过id获取总工资,然后更新游标中的列,但它很重。。。还有别的办法吗 DECLARE @id INT ; DECLARE @s INT ; DECLARE curs CURSOR FOR SELECT personid FROM dbo.Employees OPEN curs ; FETCH NEXT FR
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 ;
光标不是必需的,只需使用递归公共表表达式即可:
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
光标不是必需的,只需使用递归公共表表达式即可:
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
创建一个函数,该函数为作为经理的每个员工执行求和:
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
然后更改Employees表,使用以下函数将TotalSalary列更改为computed列:
dbo.fn_TotalSalary(EmployeeId)
随着员工收入的增加,计算列将自动更新。然后你就可以打电话了
select * from Employees
了解详情。这样做意味着您的数据始终是100%准确和最新的,而不是潜在地检索过时的数据。创建一个函数,为作为经理的每位员工执行求和:
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
然后更改Employees表,使用以下函数将TotalSalary列更改为computed列:
dbo.fn_TotalSalary(EmployeeId)
随着员工收入的增加,计算列将自动更新。然后你就可以打电话了
select * from Employees
了解详情。这样做意味着您的数据始终是100%准确和最新的,而不是可能检索过时的数据。请使用SQL Server版本标记请使用SQL Server版本标记