Использование CTE для получения иерархии emp независимо от позиции - PullRequest
2 голосов
/ 18 марта 2019

Я смотрю на создание запроса иерархии с использованием CTE.Однако в предложении where мне не хватает чего-то, запрос должен возвращать полную иерархию сотрудника

. Здесь скрипта SQL , которую я создал.

Ожидаемые результаты:

Для id = 3 Я должен получить эти результаты:

ParentEmpId Id          Name 
----------- ----------- -----
NULL        1           A    
1           3           C    
3           6           F     

Для id = 2, я должен получить эти результаты:

ParentEmpId Id          Name 
----------- ----------- -----
NULL        1           A    
1           2           B    
2           4           D     
2           5           E     

Ответы [ 3 ]

2 голосов
/ 18 марта 2019

Из вашего ожидаемого результата кажется, что вам нужны и дети, и родители id. Следовательно, вам нужна одна иерархия для детей и одна для родителей:

WITH EmpCTE(ParentEmpId, Id, [Name], [Level]) AS
(
    SELECT ParentEmpId, Id, [Name], 0 AS [Level]
    FROM emp
    WHERE id=3
         UNION ALL
    SELECT E.ParentEmpId, E.Id, E.[Name], [Level] + 1
    FROM emp E
        INNER JOIN EmpCTE empCTE
        ON E.Id = EmpCTE.ParentEmpId 
),
 EmpCTE2(ParentEmpId, Id, [Name], [Level]) AS
(
    SELECT ParentEmpId, Id, [Name], 0 AS [Level]
    FROM emp
    WHERE id=3
         UNION ALL
    SELECT E.ParentEmpId, E.Id, E.[Name], [Level] + 1
    FROM emp E
        INNER JOIN EmpCTE2 empCTE2
        ON E.ParentEmpId = EmpCTE2.Id 
)
Select * from (
select * from EmpCTE 
Union 
select * from EmpCTE2 ) a
order by name
0 голосов
/ 18 марта 2019

Почему не так?

select data.*
from emp e
  cross apply (
    select * 
    from emp e1
    where e1.Id=e.Id
    union all
    select *
    from emp e2
    where e2.ParentEmpId=e.Id
    union all
    select e4.*
    from emp e3
      join emp e4
        on e3.ParentEmpId=e4.Id
    where e3.Id=e.Id
  ) data
where e.Id=3
0 голосов
/ 18 марта 2019

Текущий CTE, который вы используете, генерирует нисходящую иерархию данной id, а не родительскую иерархию.

Одним из решений будет созданиевторой рекурсивный CTE для генерации родительской иерархии, а затем UNION обе, как указано ниже:

WITH EmpCTE(ParentEmpId, Id, [Name], [Level]) AS
(
    SELECT ParentEmpId, Id, [Name], 0 AS [Level]
    FROM emp
    WHERE id = 2
    UNION ALL
    SELECT E.ParentEmpId, E.Id, E.[Name], [Level] + 1
    FROM emp E
        INNER JOIN EmpCTE empCTE
        ON E.ParentEmpId = EmpCTE.id
),
EmpCTE2(ParentEmpId, Id, [Name], [Level]) AS
(
    SELECT ParentEmpId, Id, [Name], 0 AS [Level]
    FROM emp
    WHERE id = 2
    UNION ALL
    SELECT E.ParentEmpId, E.Id, E.[Name], [Level] + 1
    FROM emp E
        INNER JOIN EmpCTE2 empCTE2
        ON E.id = EmpCTE2.ParentEmpId
)
SELECT * FROM EmpCTE
UNION 
SELECT * FROM EmpCTE2
ORDER BY [name]

В этом обновлена ​​база данных Fiddle , если дано id = 2, запрос возвращает:

ParentEmpId  Id  Name  Level
(null)       1   A     1
1            2   B     0
2            4   D     1
2            5   E     1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...