我有一个表格,其中有一个父/子关系,其中每个孩子的ExternalCategoryCode
列数据需要连接到父母ExternalCategoryCode
。
以下是一些损坏的示例数据,即父记录(Id = 96)
ExternalCategoryCode
NULL 。关系是通过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
---|------------------------------|----------------------|---------
编辑:
ExternalCategoryCode
。记下下面的最后两条记录( Id = 100
和 Id = 101 )都链接到ParentId
97.因为 Id = 97
ParentId
IS NOT NULL ,我们应该在树上继续,直到我们
查找ParentId
为NULL(最顶级父项)的记录。ExternalCategoryCode
是否包含重复项?以下示例显示M2 *两次。这很好,因为我们的业务逻辑类库在找到任何重复项时会过滤掉重复项。如果某条记录在其ParentId
(即儿童)中有一个链接,但的字符为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
---|------------------------------|----------------------|---------
表中还有其他父/子损坏。我如何:
将此脚本编入到有问题的表格中,并将其连接起来
父记录ExternalCategoryCode
与孩子
ExternalCategoryCode
数据?
列出更新的父记录。通常在使用UPDATED
时,这只是显示这样的内容,我想报告一下:
(1行(s)受影响)
Techology Im使用:
答案 0 :(得分: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;
OUTPUT 使用递归cte为每个子项分配顶级父级。然后使用XML PATH连接所有CategoryCode
答案 1 :(得分:1)
这个很难。试试这个。
CREATE TABLE #Table1
([Id] int, [Name] varchar(29), [ExternalCategoryCode] nvarchar(max), [ParentId] varchar(4))
;
INSERT INTO #Table1
([Id], [Name], [ExternalCategoryCode], [ParentId])
VALUES
(96, 'Health & Personal Development', NULL, NULL),
(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')
;
WITH cte AS (
SELECT
Id
, ParentId AS Direct_Parent
, Id AS Orig_Parent
, ExternalCategoryCode
FROM
#Table1
WHERE
ParentId IS NULL
UNION ALL
SELECT
t1.Id
, t1.ParentId
, cte.Orig_Parent
, t1.ExternalCategoryCode
FROM
#Table1 t1
JOIN cte ON t1.ParentId = cte.Id
), tmp1 AS (
SELECT DISTINCT
Orig_Parent
, ExternalCategoryCode
FROM
cte
WHERE
Id <> Orig_Parent
AND ExternalCategoryCode IS NOT NULL
), tmp2 AS ( -- If there are too many children, this one might be needed, other wise, just use tmp1 in tmp3 below
SELECT DISTINCT
Orig_parent
FROM
tmp1
), tmp3 AS (
SELECT
tmp2.Orig_Parent,
(
SELECT CONCAT(tmp1.ExternalCategoryCode,',')
FROM
tmp1
WHERE
tmp1.Orig_parent = tmp2.Orig_Parent
FOR XML PATH(''),type).value('.','NVARCHAR(MAX)')
AS New_string
FROM
tmp2
)
UPDATE tab
SET ExternalCategoryCode = tmp3.New_string
FROM #Table1 tab JOIN tmp3 ON tab.Id = tmp3.Orig_Parent
SELECT *
FROM
#Table1;
DROP TABLE #Table1;