我正在考虑使用CTE创建层次结构查询。但是,我在where子句中缺少某些内容,查询应该返回员工的完整层次结构
这是我创建的 a SQL fiddle 。
预期结果:
对于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
答案 0 :(得分:2)
从您的预期输出看来,您既需要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
答案 1 :(得分:0)
您正在使用的当前CTE会生成给定id
的降序层次结构,而不是 parent 层次结构。
一种解决方案是创建第二个递归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]
在此 updated DB Fiddle 中,当给定id = 2
时,查询返回:
ParentEmpId Id Name Level
(null) 1 A 1
1 2 B 0
2 4 D 1
2 5 E 1
答案 2 :(得分:0)
为什么不这样呢?
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