Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server更新嵌套层次结构_Sql Server_Recursion_Common Table Expression - Fatal编程技术网

Sql server SQL Server更新嵌套层次结构

Sql server SQL Server更新嵌套层次结构,sql-server,recursion,common-table-expression,Sql Server,Recursion,Common Table Expression,我试图解决我认为是嵌套递归的问题。我有这样一个示例表:- Employee Manager IsPartTime? A Null 0 B A 1 C B 1 D C 0 E B 0 这是带有IsPartTime标志的简单员工经理问题表。因为兼职员工不

我试图解决我认为是嵌套递归的问题。我有这样一个示例表:-

Employee    Manager     IsPartTime?
A           Null            0
B           A               1
C           B               1
D           C               0
E           B               0
这是带有IsPartTime标志的简单员工经理问题表。因为兼职员工不是永久性员工,所以他不能成为任何永久性员工的经理。因此,我需要更新D&E员工的resp。更正层次结构中的下一级管理器。因此,我正在努力实现:-

Employee    Updated Manager    Old Manager
A               Null                -
B               A                   -
C               B                   -
D               A                   C
E               A                   B
我试图使用递归CTE创建一个临时表,但问题是我只得到了1级,但我需要向上遍历,直到找到任何永久的管理者

;WITH EmployeeCTE AS
    (
        SELECT EmployeeId, ManagerId
        FROM Employee
        where Manager in ('C', 'B')

        UNION ALL

        select e.EmployeeId, e.ManagerId
        from Employee e
        inner join EmployeeCTE  cc 
            on e.Manager = cc.Employee
    )
    select * from EmployeeCTE

假设我对数据的解释是正确的,下面是我得到的:

-- first, establish the hierarchy and while doing that
-- add a hierarchyid column
with d as (select * from (
    values
        (1, 'A', Null, 0),
        (2, 'B', 'A',  1),
        (3, 'C', 'B',  1),
        (4, 'D', 'C',  0),
        (5, 'E', 'B',  0)
    ) as x(ID, Employee, Manager, IsPartTime)
)
, r as (
    select ID, Employee, Manager, IsPartTime, cast(concat('/', d.ID, '/') as varchar(max)) as h
    from d
    where Manager is null

    union all

    select child.ID, child.Employee, child.Manager, child.IsPartTime, cast(concat(parent.h, child.ID, '/') as varchar(max)) as h
    from r as parent
    join d as child
        on child.Manager = parent.Employee
)
select ID, Employee, Manager, IsPartTime, cast(h as hierarchyid) as h
into #t
from r;
完成了最难的部分后,现在我们可以查看谁需要使用hierarchyid和相关子查询进行更新

with u as (
    select *, (
        select top(1) Employee
        from #t as a
        -- this person is a subordinate of the person from the main table
        where t.h.IsDescendantOf(a.h) = 1 
            -- exclude the employee themselves from consideration
            and t.ID <> a.ID
            -- the manager needs to be full-time.
            and a.IsPartTime = 0
        order by a.h.GetLevel()
    ) as NewManager
    from #t as t
    where IsPartTime = 0
)
select *
from u
where Manager <> NewManager;

澄清一件事,为什么不更新员工C?按照我阅读数据的方式,C的经理是B,B是兼职员工。因为C也是兼职员工。谢谢你的努力,我没有得到什么IsDescendatof&GetLevel?它们是独立的功能吗?在这种情况下,这将使解决方案变得非常复杂。顺便说一句,我已经用标志和While循环解决了我的问题。Hierarchyid是一种内置的CLR数据类型。因此,它有可以针对它调用的方法。这两个函数都是这样的方法。至于复杂性,大部分代码都是以一种易于查询的方式构造数据。如果你不想用它,它不会打扰我;不管怎样,我都从练习中得到了一些东西。