Иерархия TSQL Manager - PullRequest
       24

Иерархия TSQL Manager

0 голосов
/ 20 ноября 2018

Мне нужно, чтобы все мои менеджеры отображались в иерархии в разных столбцах.Я не знаю, сколько будет уровней.

Пример: Сотрудник - ManagerOfEmployee - TheBigBoss

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

Мне нужно, чтобы результаты выглядели так:

Level1Column   Level2Column   Level3Column
------------------------------------------
     1              2              3

Код:

CREATE TABLE #tblHRData
(
    Emplid          INT,
    ReportsToEmplid INT
)

INSERT INTO #tblHRData (Emplid, ReportsToEmplid)
VALUES (1, 2), (2, 3)

;WITH CTE AS
(
    SELECT  
        Emplid,
        ReportsToEmplid,
        1 AS level
    FROM    
        #tblHRData
    WHERE   
        Emplid = 1

    UNION ALL

    SELECT  
        child.Emplid,
        child.ReportsToEmplid,
        level + 1
    FROM    
        #tblHRData child
    JOIN    
        CTE parent ON child.ReportsToEmplid = parent.Emplid
)
SELECT * 
FROM CTE;

1 Ответ

0 голосов
/ 20 ноября 2018

С неизвестной глубиной вам придется пройти по динамическому маршруту SQL .Но такие случаи, как правило, имеют максимальную глубину.Поскольку ваши столбцы будут иметь вычислимых имен , вы можете попробовать это:

Я немного улучшил вашу таблицу:

CREATE TABLE #tblHRData
(
    Emplid          INT,
    ReportsToEmplid INT,
    Descr           VARCHAR(100) 
)

INSERT INTO #tblHRData (Emplid, ReportsToEmplid, Descr)
VALUES (1, 2, 'lvl 3.2.1') --boss is 2
      ,(2, 3, 'lvl 3.2')   --boss is 3
      ,(3,null, 'big boss')--big boss reports to no one
      ,(4, 3, 'lvl 3.4')   --one more 2nd lvl
      ,(5, 4, 'lvl 3.4.5') --below 4
      ,(6, 4, 'lvl 3.4.6') --another one below 4 

- И я изменил рекурсивный CTE наначните с большого босса и постройте строку сортировки на лету .В этом случае это ограничено 3 цифрами.Вам придется расширить это значение, если Emplid s превышает 999:

;WITH CTE AS
(
    SELECT  
        Emplid,
        ReportsToEmplid,
        Descr,
        0 AS EmpLvl,
        CAST(REPLACE(STR(Emplid,3),' ','0') AS VARCHAR(MAX)) AS SortOrder
    FROM    
        #tblHRData
    WHERE   
        ReportsToEmplid IS NULL --start with the big boss

    UNION ALL

    SELECT  
        child.Emplid,
        child.ReportsToEmplid,
        child.Descr,
        parent.EmpLvl + 1,
        parent.SortOrder + REPLACE(STR(child.Emplid,3),' ','0')
    FROM    
        #tblHRData child
    JOIN    
        CTE parent ON child.ReportsToEmplid = parent.Emplid
)
SELECT Emplid,
       SortOrder, 
       MAX(CASE WHEN EmpLvl=0 THEN Descr END) AS BossDescr,
       MAX(CASE WHEN EmpLvl=1 THEN Descr END) AS Lvl1Descr,
       MAX(CASE WHEN EmpLvl=2 THEN Descr END) AS Lvl2Descr,
       MAX(CASE WHEN EmpLvl=3 THEN Descr END) AS Lvl3Descr,
       MAX(CASE WHEN EmpLvl=4 THEN Descr END) AS Lvl4Descr,
       MAX(CASE WHEN EmpLvl=5 THEN Descr END) AS Lvl5Descr
       --add as many as you need and add some more to be future safe
FROM CTE
GROUP BY EmpLvl,Emplid,SortOrder
ORDER BY SortOrder;
GO
DROP TABLE #tblHRData

Результат

+--------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
| Emplid | SortOrder | BossDescr | Lvl1Descr | Lvl2Descr | Lvl3Descr | Lvl4Descr | Lvl5Descr |
+--------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
| 3      | 003       | big boss  | NULL      | NULL      | NULL      | NULL      | NULL      |
+--------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
| 2      | 003002    | NULL      | lvl 3.2   | NULL      | NULL      | NULL      | NULL      |
+--------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
| 1      | 003002001 | NULL      | NULL      | lvl 3.2.1 | NULL      | NULL      | NULL      |
+--------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
| 4      | 003004    | NULL      | lvl 3.4   | NULL      | NULL      | NULL      | NULL      |
+--------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
| 5      | 003004005 | NULL      | NULL      | lvl 3.4.5 | NULL      | NULL      | NULL      |
+--------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
| 6      | 003004006 | NULL      | NULL      | lvl 3.4.6 | NULL      | NULL      | NULL      |
+--------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+

Некоторые замечания:
- я использую условная агрегация при PIVOT подходе.Только с одним столбцом это можно сделать и с PIVOT().- SortOrder важно создать в рекурсии.Это своего рода путь к записи и позволит вам упорядочить набор результатов.- Этот путь должен разрешать буквенно-цифровую сортировку.Поэтому я объединяю мягкие строки.

...