Требуется помощь / совет по рекурсивным запросам с использованием CTE - PullRequest
0 голосов
/ 23 сентября 2019

Я пытаюсь получить повторных сотрудников (менеджеры - директор - генеральный директор, чтобы иметь полную иерархию) с DepartmentCode аналогично столбцу Lvl из результата рекурсивного запроса.

Найдена пара существующих вопросов и ответов, но они, похоже, не соответствуют моему случаю.Цель состоит в том, чтобы иметь полную иерархию до корневого узла (CEO), когда данные результата фильтруются с любым значением DepartmentCode.Когда я попробовал использовать следующий рекурсивный CTE, он отлично смотрится со столбцом Lvl, т. Е. Когда данные фильтруют любой идентификатор столбца Lvl, он получает сотрудников, менеджеров, директоров и генерального директора (полная цепочка иерархии).

Мне интересно, может ли то же самое быть применено к столбцу DepartmentCode с использованием Recursive CTE или с использованием другого подхода.Любой совет будет заметен!

Запрос, который я пытался , результат здесь .. (я в порядке с дублирующимися значениями, которые появляются в результате)

WITH CTE AS  
        (
            SELECT E.EmployeeID, E.EmpName, E.Title, DepartmentCode, '   ' DepartTest, E.ManagerID, 1 as Lvl
            FROM MyEmployees AS E
        UNION ALL
            SELECT E.EmployeeID, E.EmpName, E.Title, E.DepartmentCode, E.DepartmentCode, E.ManagerID, Lvl + 1
            FROM MyEmployees AS E
                JOIN CTE ON E.EmployeeID = CTE.ManagerID
                --E.ManagerID = CTE.EmployeeID
          ) 
SELECT * FROM CTE
Order by Lvl
go

Пример сценария данных:

    CREATE TABLE dbo.MyEmployees
    (
        EmployeeID smallint NOT NULL,
        EmpName nvarchar(30)  NOT NULL,
        Title nvarchar(50) NOT NULL,
        DepartmentCode varchar(3),
        ManagerID int NULL,
     CONSTRAINT PK_EmployeeID PRIMARY KEY CLUSTERED (EmployeeID ASC) 
    );


    -- Populate the table with values.
    INSERT INTO dbo.MyEmployees 
    (EmployeeID, EmpName, Title, DepartmentCode, ManagerID)
    VALUES 
     (1,   N'Ken',  N'Chief Executive Officer', 'SMG', NULL)
    ,(201, N'Brian',  N'Director', 'OPD',1)
    ,(301, N'Stephen', N'IT Manager', 'ICT',201)
    ,(302, N'Michael', N'IT Position1','ICT',301)
    ,(303, N'Linda', N'IT Position2','ICT', 301)
    ,(401, N'Syed', N'Procurement Position1','PRO',201)
    ,(402, N'Abbas', N'Procurement Position1','PRO',401)
    ,(403, N'Lynn', N'Procurement Position2','PRO',401)
    GO

1 Ответ

1 голос
/ 23 сентября 2019

Это изменение кода может помочь Вам

;WITH CTE
AS
(
SELECT 
         EmployeeID
        ,EmpName
        ,ManagerID
        ,CAST('\'+EmpName AS VARCHAR(100)) AS ManagerName
        ,1 as Lvl

FROM MyEmployees
WHERE managerid IS NULL
union all
SELECT 
         e.EmployeeID
        ,e.EmpName
        , e.ManagerID
         ,CAST(ManagerName+'\'+c.EmpName AS VARCHAR(100)) AS ManagerName
         , Lvl+1
FROM CTE c
INNER JOIN MyEmployees e
ON c.EmployeeID = e.ManagerID

)
SELECT  EmployeeID, 
        EmpName,
        ManagerID,
        RIGHT(ManagerName,LEN(ManagerName)-1) AS ManagerName,
        Lvl
FROM CTE
GO

Результат

EmployeeID  EmpName ManagerID   ManagerName                 Lvl
*****************************************************************
1            Ken        NULL    Ken                          1
201          Brian      1       Ken\Ken                      2
301          Stephen    201     Ken\Ken\Brian                3
401          Syed       201     Ken\Ken\Brian                3
402          Abbas      401     Ken\Ken\Brian\Syed           4
403          Lynn       401     Ken\Ken\Brian\Syed           4
302          Michael    301     Ken\Ken\Brian\Stephen        4
303          Linda      301     Ken\Ken\Brian\Stephen        4

Скорректированный запрос (согласно комментарию):

;WITH CTE
AS
(
SELECT 
         EmployeeID
        ,Title
        ,ManagerID
        ,DepartmentCode 
        ,1 as Lvl

FROM MyEmployees
--WHERE managerid IS NULL
union all
SELECT 
         e.EmployeeID
        ,e.Title
        ,e.ManagerID
         ,c.DepartmentCode
         , Lvl+1
FROM CTE c 
INNER JOIN MyEmployees e
ON c.ManagerID = e.EmployeeID

)
SELECT  EmployeeID, 
        Title,
        ManagerID,
        DepartmentCode,
        --RIGHT(ManagerName,LEN(ManagerName)-1) AS ConcatManagerName,
        Lvl
FROM CTE
Order by DepartmentCode
...