我有这张桌子
emp_no unq_key emp_id mgr_id
7518870 2244087948 2244087965 2244087948
7518870 2244087948 2333920909 2244087948
7518870 2244087948 2244087950 2244087948
7518870 2244087948 2244087948 2340921616
7518870 2244087948 2244087963 2244087948
7518870 2244087948 2244087962 2244087961
7518870 2244087948 2244088015 2244087951
7518870 2244087948 2358036768 2244087955
7518870 2244087948 2244087952 2244087951
7518870 2244087948 2244087953 2244087952
7518870 2244087948 2244460352 2244087965
7518870 2244087948 2244087957 2244087948
7518870 2244087948 2277248665 2277248664
7518870 2244087948 2277248667 2244087965
7518870 2244087948 2340921670 2244087955
7518870 2244087948 2244087959 2244087948
7518870 2244087948 2244087960 2244087948
7518870 2244087948 2352651692 2244087951
7518870 2244087948 2314063120 2244087955
7518870 2244087948 2244088014 2244087952
7518870 2244087948 2244087954 2244087951
7518870 2244087948 2244087956 2244087955
7518870 2244087948 2244087955 2244087951
7518870 2244087948 2277248664 2244087951
7518870 2244087948 2280898236 2277248645
7518870 2244087948 2277248645 2244087951
7518870 2244087948 2358036769 2244087948
7518870 2244087948 2244087958 2244087948
7518870 2244087948 2244088016 2244088015
7518870 2244087948 2244087951 2244087948
我的根记录是unq_key=emp_id。我正在尝试打印所有叶节点的第一个相应的 emp_id 子节点。我正在尝试识别下面的代码,但没有得到正确的第一个孩子。
例如:2244088016是第一个子节点的叶节点:2244087951
如有任何帮助,我们将不胜感激。预先感谢。
;WITH tree_view AS (
SELECT
emp_no
,unq_key
,emp_id
,mgr_id
,0 AS order_sequence
,0 AS generation_number
FROM
#temp_employees
WHERE
unq_key=emp_id
UNION ALL
SELECT
parent.emp_no,
parent.unq_key,
parent.emp_id,
parent.mgr_id
,order_sequence +1 AS order_sequence
,generation_number + 1 AS generation_number
FROM
#temp_employees parent
JOIN tree_view tv
ON parent.mgr_id = tv.emp_id
)
SELECT
RIGHT('------------',generation_number*3) + ' Emp :'+ cast( emp_id as varchar(100))
,*
FROM
tree_view
ORDER BY order_sequence;
只需要一个包含第一个孩子的附加列。
我将“第一个子节点”解释为“给定从根到每个叶子的路径,找到根之后的第一个节点”。换句话说,对于根节点来说,没有第一个子节点,而对于根节点的所有直接子节点来说,第一个子节点就是它自己。
如果这是正确的,这里有一个使用闭包表的解决方案。闭包表包含从每个节点到其谱系中每个其他节点的边(不仅到其父节点,还包括其父节点的父节点,等等,一直到根),深度是节点之间的距离。
请注意,为了做到这一点,递归 CTE 从叶级别而不是根级别开始。
with emps as
(
select *
from
(
values
(7518870, 2244087948, 2244087965, 2244087948),
(7518870, 2244087948, 2333920909, 2244087948),
(7518870, 2244087948, 2244087950, 2244087948),
(7518870, 2244087948, 2244087948, 2340921616),
(7518870, 2244087948, 2244087963, 2244087948),
(7518870, 2244087948, 2244087962, 2244087961),
(7518870, 2244087948, 2244088015, 2244087951),
(7518870, 2244087948, 2358036768, 2244087955),
(7518870, 2244087948, 2244087952, 2244087951),
(7518870, 2244087948, 2244087953, 2244087952),
(7518870, 2244087948, 2244460352, 2244087965),
(7518870, 2244087948, 2244087957, 2244087948),
(7518870, 2244087948, 2277248665, 2277248664),
(7518870, 2244087948, 2277248667, 2244087965),
(7518870, 2244087948, 2340921670, 2244087955),
(7518870, 2244087948, 2244087959, 2244087948),
(7518870, 2244087948, 2244087960, 2244087948),
(7518870, 2244087948, 2352651692, 2244087951),
(7518870, 2244087948, 2314063120, 2244087955),
(7518870, 2244087948, 2244088014, 2244087952),
(7518870, 2244087948, 2244087954, 2244087951),
(7518870, 2244087948, 2244087956, 2244087955),
(7518870, 2244087948, 2244087955, 2244087951),
(7518870, 2244087948, 2277248664, 2244087951),
(7518870, 2244087948, 2280898236, 2277248645),
(7518870, 2244087948, 2277248645, 2244087951),
(7518870, 2244087948, 2358036769, 2244087948),
(7518870, 2244087948, 2244087958, 2244087948),
(7518870, 2244087948, 2244088016, 2244088015),
(7518870, 2244087948, 2244087951, 2244087948)
) t (emp_no, unq_key, emp_id, mgr_id)
),
closure as
(
select emp_id = emp_id,
mgr_id = emp_id,
emp_no,
unq_key,
distance = 0
from emps
union all
select e.emp_id,
c.mgr_id,
e.emp_no,
e.unq_key,
c.distance + 1
from emps e
join closure c on c.emp_id = e.mgr_id
)
select tree = concat(replicate('-', tree.distance * 3), ' Emp :', tree.emp_id),
tree.emp_no,
tree.unq_key,
tree.emp_id,
tree.mgr_id,
tree.distance,
first_child = tier0.mgr_id
from (select * from closure where mgr_id = unq_key) tree
outer apply (select mgr_id from closure where emp_id = tree.emp_id and distance = tree.distance - 1) tier0
order by tree.distance;
tree
子查询用于仅获取闭包表中表示从每个叶子到根的边的行。从根开始的这些行的 distance
提供了所需的缩进级别。
tier0
子查询然后找到距离比到根的距离小一的叶子的边缘。