Sql server CTE get parent';s子对象,然后使用父对象值更新子对象
如何循环遍历所有子节点并为所有节点更新一列?例如,如果我在“OrganizationLevelId”列的父级。如果我更新父行上的“OrganizationLevelId”,它应传播给子行,因此父行的所有子行以及子行的子行在“OrganizationLevelId”中应具有相同的值 我有以下cte:Sql server CTE get parent';s子对象,然后使用父对象值更新子对象,sql,sql-server,common-table-expression,Sql,Sql Server,Common Table Expression,如何循环遍历所有子节点并为所有节点更新一列?例如,如果我在“OrganizationLevelId”列的父级。如果我更新父行上的“OrganizationLevelId”,它应传播给子行,因此父行的所有子行以及子行的子行在“OrganizationLevelId”中应具有相同的值 我有以下cte: WITH cte as (select h.Name, h.ID, h.OrganisationLevelID, h.parentId From organisations h WHERE ID =
WITH cte as
(select h.Name, h.ID, h.OrganisationLevelID, h.parentId
From organisations h
WHERE ID = '3eea8c17-1bfd-46d5-9ea9-2d11652d23a4'
UNION ALL
select p.Name, p.ID, p.OrganisationLevelID, p.parentId
FROM organisations p
INNER JOIN cte c ON c.Id = p.parentId)
SELECT * FROM cte
这将获得父子层次结构,并且工作正常
如何更新子级值,使它们都具有父级的“OrganizationLevelId”
如果您希望更新
组织
表中的实际记录,我相信您可以尝试以下方法:
;WITH cte
AS (
SELECT h.Name
, h.ID
, h.OrganisationLevelID
, h.parentId
FROM organisations h
WHERE ID = '3eea8c17-1bfd-46d5-9ea9-2d11652d23a4'
UNION ALL
SELECT p.Name
, p.ID
, c.OrganisationLevelID -- note that I changed the alias from "p" to "c" to use the parent's value
, p.parentId
FROM organisations p
INNER JOIN cte c
ON c.Id = p.parentId
)
UPDATE org
SET OrganisationLevelID = cte.OrganisationLevelID
FROM organisations org
INNER JOIN cte
ON org.id = cte.id
您可以使用以下示例代码查看将发生什么,特别是父行的orgValueId中的值将“传播”到其所有子行和子行:
create table #t (id int, parentid int, orgValueId varchar(10));
insert into #t values (1, null, 'x'), (2, 1, 'o'), (3, 1, 'm'), (4, 2, 'v'), (5, 3, 'p');
select *
from #t;
with cte as (
select id
, orgValueId
from #t
where parentid is null
union all
select t.id
, c.orgValueId
from cte c
inner join #t t on c.id = t.parentid)
update t
set orgValueId = c.orgValueId
from #t t
inner join cte c
on t.id = c.id;
select *
from #t;
样本数据和期望的结果真的很有帮助。这非常有效,谢谢Radu!我最大的错误是在创建层次结构时没有从cte中选择父级的OrganizationLevelId。
create table #t (id int, parentid int, orgValueId varchar(10));
insert into #t values (1, null, 'x'), (2, 1, 'o'), (3, 1, 'm'), (4, 2, 'v'), (5, 3, 'p');
select *
from #t;
with cte as (
select id
, orgValueId
from #t
where parentid is null
union all
select t.id
, c.orgValueId
from cte c
inner join #t t on c.id = t.parentid)
update t
set orgValueId = c.orgValueId
from #t t
inner join cte c
on t.id = c.id;
select *
from #t;