Sql server CTE get parent';s子对象,然后使用父对象值更新子对象

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 =

如何循环遍历所有子节点并为所有节点更新一列?例如,如果我在“OrganizationLevelId”列的父级。如果我更新父行上的“OrganizationLevelId”,它应传播给子行,因此父行的所有子行以及子行的子行在“OrganizationLevelId”中应具有相同的值

我有以下cte

 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;