如何使用 CTE 递归扩展 parent-child 层次结构
How to expand parent-child hierarchy recursively using CTE
我正在尝试使用 Azure SQL 数据库中的 CTE 扩展 self-referencing table,但尚未成功。
来源table有列Id,ParentId,例如:
Id ParentId
1 NULL
2 1
3 2
4 2
5 4
6 4
7 NULL
8 7
我想要的结果是这样的:(每个 id 一行,它是 child 或 grandchild 或 ...)
Id ChildId
1 1
1 2
1 3
1 4
1 5
1 6
2 2
2 3
2 4
2 5
2 6
3 3
4 4
4 5
4 6
5 5
6 6
7 7
7 8
8 8
有什么方法可以使用 CTE 或 SQL table-valued 函数来做到这一点?
我会使用上面 link 中的示例代码作为起点。这段代码依赖于流行的 AdventureWorks 数据库。
F。使用递归通用 table 表达式显示分层列表
USE AdventureWorks2012;
GO
WITH DirectReports(Name, Title, EmployeeID, EmployeeLevel, Sort)
AS (SELECT CONVERT(varchar(255), e.FirstName + ' ' + e.LastName),
e.Title,
e.EmployeeID,
1,
CONVERT(varchar(255), e.FirstName + ' ' + e.LastName)
FROM dbo.MyEmployees AS e
WHERE e.ManagerID IS NULL
UNION ALL
SELECT CONVERT(varchar(255), REPLICATE ('| ' , EmployeeLevel) +
e.FirstName + ' ' + e.LastName),
e.Title,
e.EmployeeID,
EmployeeLevel + 1,
CONVERT (varchar(255), RTRIM(Sort) + '| ' + FirstName + ' ' +
LastName)
FROM dbo.MyEmployees AS e
JOIN DirectReports AS d ON e.ManagerID = d.EmployeeID
)
SELECT EmployeeID, Name, Title, EmployeeLevel
FROM DirectReports
ORDER BY Sort;
AdventureWorks 架构
Visio ER图表可以从这里获得
https://www.microsoft.com/en-us/download/confirmation.aspx?id=10331
为此您需要一个递归 CTE:
with cte as (
select id, id as childid, 1 as lev
from t
-- where parentid is null
union all
select cte.id, t.id, lev + 1
from cte join
t
on cte.childid = t.parentid
where lev < 10 and t.id <> cte.id
)
select id, childid
from cte
order by id, childid;
Here 是一个 db<>fiddle.
我正在尝试使用 Azure SQL 数据库中的 CTE 扩展 self-referencing table,但尚未成功。
来源table有列Id,ParentId,例如:
Id ParentId
1 NULL
2 1
3 2
4 2
5 4
6 4
7 NULL
8 7
我想要的结果是这样的:(每个 id 一行,它是 child 或 grandchild 或 ...)
Id ChildId
1 1
1 2
1 3
1 4
1 5
1 6
2 2
2 3
2 4
2 5
2 6
3 3
4 4
4 5
4 6
5 5
6 6
7 7
7 8
8 8
有什么方法可以使用 CTE 或 SQL table-valued 函数来做到这一点?
我会使用上面 link 中的示例代码作为起点。这段代码依赖于流行的 AdventureWorks 数据库。
F。使用递归通用 table 表达式显示分层列表
USE AdventureWorks2012;
GO
WITH DirectReports(Name, Title, EmployeeID, EmployeeLevel, Sort)
AS (SELECT CONVERT(varchar(255), e.FirstName + ' ' + e.LastName),
e.Title,
e.EmployeeID,
1,
CONVERT(varchar(255), e.FirstName + ' ' + e.LastName)
FROM dbo.MyEmployees AS e
WHERE e.ManagerID IS NULL
UNION ALL
SELECT CONVERT(varchar(255), REPLICATE ('| ' , EmployeeLevel) +
e.FirstName + ' ' + e.LastName),
e.Title,
e.EmployeeID,
EmployeeLevel + 1,
CONVERT (varchar(255), RTRIM(Sort) + '| ' + FirstName + ' ' +
LastName)
FROM dbo.MyEmployees AS e
JOIN DirectReports AS d ON e.ManagerID = d.EmployeeID
)
SELECT EmployeeID, Name, Title, EmployeeLevel
FROM DirectReports
ORDER BY Sort;
AdventureWorks 架构
Visio ER图表可以从这里获得 https://www.microsoft.com/en-us/download/confirmation.aspx?id=10331
为此您需要一个递归 CTE:
with cte as (
select id, id as childid, 1 as lev
from t
-- where parentid is null
union all
select cte.id, t.id, lev + 1
from cte join
t
on cte.childid = t.parentid
where lev < 10 and t.id <> cte.id
)
select id, childid
from cte
order by id, childid;
Here 是一个 db<>fiddle.