【问题标题】:Update Manager Table Tree by Recursion递归更新管理器表树
【发布时间】:2012-06-05 11:56:13
【问题描述】:

我有一张表(查看图片)员工(经理是另一个经理,依此类推),其中包含 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 ;

【问题讨论】:

  • 请标记您的 SQL Server 版本

标签: tsql recursion sql-server-2008-r2 sum with-statement


【解决方案1】:

游标不是必需的,这可以使用递归公用表表达式来完成:

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

【讨论】:

    【解决方案2】:

    创建一个函数,对作为经理的每个员工执行求和:

    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% 准确和最新的,而不是可能检索过时的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-28
      • 2011-01-28
      • 2019-07-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多