一尘不染

使用子记录数据(同一表)更新父记录的字段

sql

我有一个表格,其中有一个父/子关系,其中每个孩子的ExternalCategoryCode列数据都需要连接到父母中ExternalCategoryCode

这是一些示例数据,该数据已损坏,因此父记录(Id = 96) ExternalCategoryCodeNULL
。关系是通过ParentId字段进行的:

Id |Name                          |ExternalCategoryCode|ParentId
---|------------------------------|--------------------|--------- 
96 | Health & Personal Development| NULL               | NULL
---|------------------------------|--------------------|---------
97 | Health                       | H1*;H2*            | 96
---|------------------------------|--------------------|---------
98 | Personal Development         | P1;P2;P3*          | 96
---|------------------------------|--------------------|---------
99 | Other Health                 | OH*                | 96
---|------------------------------|--------------------|---------

数据应如下所示:

Id |Name                          |ExternalCategoryCode  |ParentId
---|------------------------------|----------------------|--------- 
96 | Health & Personal Development| H1*;H2*;P1;P2;P3*;OH*| NULL
---|------------------------------|----------------------|---------
97 | Health                       | H1*;H2*              | 96
---|------------------------------|----------------------|---------
98 | Personal Development         | P1;P2;P3*            | 96
---|------------------------------|----------------------|---------
99 | Other Health                 | OH*                  | 96
---|------------------------------|----------------------|---------

编辑:

  1. 后代级别可以是任何深层次,但深子级后代需要更新为主要的父级 ExternalCategoryCode。拿下面的最后两个记录( Id = 100Id = 101 )都链接到ParentId97。因为 Id = 97 ParentId IS NOT NULL ,所以我们应该继续树直到找到具有ParentIdNULL的记录(最高父级)。
  2. 另一个问题是关于最高父母的ExternalCategoryCode副本是否可以重复?下面的示例两次显示M2 *。很好,因为我们的业务逻辑类库会在发现重复项时过滤掉重复项。
  3. 如果一条记录中有一个链接ParentId(即是一个子项), 但是 具有NULL ExternalCategoryCode,则可以忽略这些代码。
    Id |Name                          |ExternalCategoryCode  |ParentId
    

    —|------------------------------|----------------------|---------
    96 | Health & Personal Development| H1;H2;P1;P2;P3;OH| NULL
    | | |
    | | M1;M2; M2;M3 |
    —|------------------------------|----------------------|---------
    97 | Health | H1
    ;H2 | 96
    —|------------------------------|----------------------|---------
    98 | Personal Development | P1;P2;P3
    | 96
    —|------------------------------|----------------------|---------
    99 | Other Health | OH | 96
    —|------------------------------|----------------------|---------
    100| Medicine | M1;M2
    | 97
    —|------------------------------|----------------------|---------
    101| Other Medicine | M2;M3 | 97
    —|------------------------------|----------------------|---------
    102| Other Medicine 2 | NULL | 97
    —|------------------------------|----------------------|---------

表格中还有其他“父/子”损坏。我如何能:

  1. 使用脚本将此脚本放到有问题的表中,并将父记录ExternalCategoryCode与子ExternalCategoryCode数据合并起来 ?

  2. 列出更新的父记录。通常在使用时UPDATED,这仅显示如下内容,据此我要报告一下:

(影响1行)

我使用的技术:

  • SQL服务器

阅读 268

收藏
2021-03-08

共1个答案

一尘不染

SQL DEMO 首先将来自同一父级的所有代码连接起来,然后进行更新。

WITH superParent as (
    SELECT [Id], [Id] as [topParent], [Name], [ExternalCategoryCode], [ParentId]
    FROM Table1 t
    WHERE [ParentId] is NULL
    UNION ALL
    SELECT t.[Id], sp.[topParent], t.[Name], t.[ExternalCategoryCode], t.[ParentId]    
    FROM Table1 t
    JOIN superParent sp
      ON sp.[id] = t.[ParentId]
),  
combine as (
    Select distinct ST2.[topParent], 
        (
            Select ST1.[ExternalCategoryCode] + ';' AS [text()]
            From superParent ST1
            Where ST1.[topParent] = ST2.[topParent]
            ORDER BY ST1.[Id]
            For XML PATH ('')
        ) [External]
    From superParent ST2
    WHERE ST2.[ParentId] IS NOT NULL    
)    
UPDATE T
SET T.[ExternalCategoryCode] = C.[External]
FROM Table1 T
JOIN combine C
  ON T.[Id] = c.[topParent];

SELECT *
FROM Table1;

*使用递归cte的 *输出 将顶级父级分配给每个子级。然后使用XML PATH串联所有CategoryCode

在此处输入图片说明

2021-03-08