Рекурсивный CTE, находящий первого менеджера в иерархии в SQL Server - PullRequest
0 голосов
/ 07 января 2020

У меня есть таблица пользователей

enter image description here

, и я хочу найти для каждого пользователя своего первого менеджера по иерархии его рабочих мест.

Мне удалось написать этот скрипт, но я не могу заставить его работать должным образом. Мне нужно, чтобы у пользователя 1003 был 1001 managerId. Теперь он показывает 1002.

enter image description here

select 1001 as userid, 'L1' as locationCode, NULL as parentLocationCode, 1 as isManager into #Users union all
select 1002 as userid, 'L2' as locationCode, 'L1' as parentPad, 0 as isManager union all
select 1003 as userid, 'L3' as locationCode, 'L2' as parentPad, 0 as isManager 

;WITH cte_org AS (
    SELECT       
        d.userid 
        ,d.locationCode
        ,d.parentLocationCode
        ,d.isManager
        ,null as managerId
    FROM       
        #Users as d
    WHERE d.parentLocationCode is NULL
    UNION ALL
    SELECT 
        d.userid 
        ,d.locationCode
        ,d.parentLocationCode
        ,d.isManager
        ,o.userid as managerId
    FROM 
        #Users as d
        inner JOIN cte_org o on d.parentLocationCode=o.locationCode
)
SELECT *
FROM cte_org
OPTION (MAXRECURSION 32767);

1 Ответ

2 голосов
/ 07 января 2020

Вам просто нужно установить managerId, используя userId для менеджера, затем скопировать managerId для связанных записей

select 1001 as userid, 'L1' as locationCode, NULL as parentLocationCode, 1 as isManager into #Users union all
select 1002 as userid, 'L2' as locationCode, 'L1' as parentPad, 0 as isManager union all
select 1003 as userid, 'L3' as locationCode, 'L2' as parentPad, 0 as isManager 
;

WITH
cte_org AS (
    SELECT       
        d.userid 
        ,d.locationCode
        ,d.parentLocationCode
        ,d.isManager
        ,d.userid as managerId
    FROM       
        #Users as d
    WHERE d.parentLocationCode is NULL
    UNION ALL
    SELECT 
        d.userid 
        ,d.locationCode
        ,d.parentLocationCode
        ,d.isManager
        ,o.managerId as managerId
    FROM 
        #Users as d
        inner JOIN cte_org o on d.parentLocationCode=o.locationCode
)
SELECT *
FROM cte_org
OPTION (MAXRECURSION 32767);

userid  locationCode    parentLocationCode  isManager   managerId
1001    L1                                  1           1001
1002    L2              L1                  0           1001
1003    L3              L2                  0           1001
...