CTE 获取根名
CTE get rootname
我得到了一个非常简单的 table,但我正在为 CTE 而苦苦挣扎:
ID | Parent | Name
---+--------+---------
1 | NULL | Root
2 | 1 | Child1
3 | 2 | Child2
我希望收到这样的结果:
Element | Root
--------+------
Root | Root
Child1 | Root
Child2 | Root
我的 CTE 是这样的...
WITH cte AS
(
SELECT a.id, a.parent, a.name, 1 as lvl
FROM table1 a
UNION ALL
-- Perform the recursive join
SELECT a.id, a.parent, a.name, Lvl+1 AS Lvl
FROM table1 a
INNER JOIN cte pa ON cte.parent = a.id
)
SELECT *
FROM cte
现在我会汇总 (max) 和 (self)join,但看起来有点 bad/wrong。
这有点复杂,因为你正在遍历 ID,但最后你只需要名称。以下通过查找名称 在 递归 CTE 找到根 ID 后处理此问题:
with cte as (
select id, parent, name, 1 as lev
from t
union all
select cte.id, t.parent, cte.name, lev + 1
from cte join
t
on t.id = cte.parent
where t.parent is not null
)
select top (1) with ties cte.name, coalesce(tparent.name, cte.name) as root
from cte left join
t tparent
on tparent.id = cte.parent
order by row_number() over (partition by cte.id order by cte.lev desc)
Here 是一个 db<>fiddle.
尝试
with cte as (
select id, parent, name, name as root
from t
where parent is null
union all
select t.id, t.parent, t.name, cte.root
from cte
join t on t.parent = cte.id
)
select name, root
from cte
我得到了一个非常简单的 table,但我正在为 CTE 而苦苦挣扎:
ID | Parent | Name
---+--------+---------
1 | NULL | Root
2 | 1 | Child1
3 | 2 | Child2
我希望收到这样的结果:
Element | Root
--------+------
Root | Root
Child1 | Root
Child2 | Root
我的 CTE 是这样的...
WITH cte AS
(
SELECT a.id, a.parent, a.name, 1 as lvl
FROM table1 a
UNION ALL
-- Perform the recursive join
SELECT a.id, a.parent, a.name, Lvl+1 AS Lvl
FROM table1 a
INNER JOIN cte pa ON cte.parent = a.id
)
SELECT *
FROM cte
现在我会汇总 (max) 和 (self)join,但看起来有点 bad/wrong。
这有点复杂,因为你正在遍历 ID,但最后你只需要名称。以下通过查找名称 在 递归 CTE 找到根 ID 后处理此问题:
with cte as (
select id, parent, name, 1 as lev
from t
union all
select cte.id, t.parent, cte.name, lev + 1
from cte join
t
on t.id = cte.parent
where t.parent is not null
)
select top (1) with ties cte.name, coalesce(tparent.name, cte.name) as root
from cte left join
t tparent
on tparent.id = cte.parent
order by row_number() over (partition by cte.id order by cte.lev desc)
Here 是一个 db<>fiddle.
尝试
with cte as (
select id, parent, name, name as root
from t
where parent is null
union all
select t.id, t.parent, t.name, cte.root
from cte
join t on t.parent = cte.id
)
select name, root
from cte