如何删除 sql 邻接表中给定根的所有节点
How to delete all nodes of given root in sql adjacency list
有这个table:
我要删除根节点,发送查询ID=1
并且我希望这个id的所有子节点也将被删除。
我该怎么做?
假设您有以下数据:
并且您想删除记录 2.1
及其所有后代(在本例中仅 2.1.3
)。可以使用以下代码获取需要删除的IDs
:
WITH DataSource ([ID], [HierarchyLevel]) AS
(
SELECT [ID]
,CAST(REPLACE('/' + [Name] + '/', '.', '/') AS HIERARCHYID)
FROM @DataSource
)
SELECT [ID]
,[HierarchyLevel].ToString()
FROM DataSource
WHERE [HierarchyLevel].IsDescendantOf('/2/1/') = 1;
基本上,我们将您的记录转换为hierarchy id
类型,并使用内置IsDescendantOf函数获取节点的所有childs
。
这是完整的工作示例:
DECLARE @DataSource TABLE
(
[ID] TINYINT
,[Name] VARCHAR(12)
,[Owner] VARCHAR(12)
,[Parent] INT
);
INSERT INTO @DataSource ([ID], [Name], [Owner], [Parent])
VALUES (1, '1', '1', NULL)
,(2, '1.1', '1.1', 1)
,(3, '1.1.1', '1.1.1', 2)
,(4, '2', '2.1', NULL)
,(5, '2.1', '2.1', 4)
,(6, '2.2', '2.2', 4)
,(7, '2.1.3', '2.1.3', 5);
WITH DataSource ([ID], [HierarchyLevel]) AS
(
SELECT [ID]
,CAST(REPLACE('/' + [Name] + '/', '.', '/') AS HIERARCHYID)
FROM @DataSource
)
DELETE @DataSource
FROM @DataSource DS
INNER JOIN DataSource DS1
ON DS.[ID] = DS1.[ID]
WHERE [HierarchyLevel].IsDescendantOf('/2/1/') = 1;
SELECT *
FROM @DataSource;
这可以使用递归通用 table 表达式来完成。
要获取一个节点的所有子节点,您可以使用:
with tree as (
select id, parent
from eyalewin
where id = 1
union all
select c.id, c.parent
from eyalewin c
join tree p on p.id = c.parent
)
select *
from tree;
这可以用来删除所有这些:
with tree as (
select id, parent
from eyalewin
where id = 1
union all
select c.id, c.parent
from eyalewin c
join tree p on p.id = c.parent
)
delete from eyalewin
where id in (select id
from tree);
有这个table:
我要删除根节点,发送查询ID=1 并且我希望这个id的所有子节点也将被删除。
我该怎么做?
假设您有以下数据:
并且您想删除记录 2.1
及其所有后代(在本例中仅 2.1.3
)。可以使用以下代码获取需要删除的IDs
:
WITH DataSource ([ID], [HierarchyLevel]) AS
(
SELECT [ID]
,CAST(REPLACE('/' + [Name] + '/', '.', '/') AS HIERARCHYID)
FROM @DataSource
)
SELECT [ID]
,[HierarchyLevel].ToString()
FROM DataSource
WHERE [HierarchyLevel].IsDescendantOf('/2/1/') = 1;
基本上,我们将您的记录转换为hierarchy id
类型,并使用内置IsDescendantOf函数获取节点的所有childs
。
这是完整的工作示例:
DECLARE @DataSource TABLE
(
[ID] TINYINT
,[Name] VARCHAR(12)
,[Owner] VARCHAR(12)
,[Parent] INT
);
INSERT INTO @DataSource ([ID], [Name], [Owner], [Parent])
VALUES (1, '1', '1', NULL)
,(2, '1.1', '1.1', 1)
,(3, '1.1.1', '1.1.1', 2)
,(4, '2', '2.1', NULL)
,(5, '2.1', '2.1', 4)
,(6, '2.2', '2.2', 4)
,(7, '2.1.3', '2.1.3', 5);
WITH DataSource ([ID], [HierarchyLevel]) AS
(
SELECT [ID]
,CAST(REPLACE('/' + [Name] + '/', '.', '/') AS HIERARCHYID)
FROM @DataSource
)
DELETE @DataSource
FROM @DataSource DS
INNER JOIN DataSource DS1
ON DS.[ID] = DS1.[ID]
WHERE [HierarchyLevel].IsDescendantOf('/2/1/') = 1;
SELECT *
FROM @DataSource;
这可以使用递归通用 table 表达式来完成。
要获取一个节点的所有子节点,您可以使用:
with tree as (
select id, parent
from eyalewin
where id = 1
union all
select c.id, c.parent
from eyalewin c
join tree p on p.id = c.parent
)
select *
from tree;
这可以用来删除所有这些:
with tree as (
select id, parent
from eyalewin
where id = 1
union all
select c.id, c.parent
from eyalewin c
join tree p on p.id = c.parent
)
delete from eyalewin
where id in (select id
from tree);