如何使用 CTE 对列进行条件更新?

How to do conditional update on columns using CTE?

我有一个 table CUST 布局如下。没有限制。我确实看到一个 ChildID 与多个 ParentID 相关联。 (请查看 ChildID = 115 的记录)

这是我需要的 -

只要一个 child 超过 1 个 parent,我想用 ParentID 和 [=15= 更新那些 ParentIDParentName ] 最大 match_per。所以在下图中,我希望 ParentID 1111 和 ParentName LEE YOUNG WOOK 更新所有 ChildId = 115 的记录(因为 match_per 0.96 在给定的集合中是最大值)。如果有两个 parent 的最大值 match_per 相等,那么我想选择其中的任意一个。

我知道可以使用 CTE,但我不知道如何更新 CTE。有人可以帮忙吗?

一种方法

WITH CTE1 AS
(
SELECT *,
       CASE WHEN match_per = 
              MAX(match_per) OVER (PARTITION BY ChildId) 
            THEN CAST(ParentId AS CHAR(10)) + ParentName 
       END AS parentDetailsForMax
FROM CUST 
), CTE2 AS
(
SELECT *,
        MAX(parentDetailsForMax) OVER (PARTITION BY ChildId) AS maxParentDetailsForMax
FROM CTE1
)
UPDATE CTE2
SET ParentId = CAST(LEFT(maxParentDetailsForMax,10) AS int), 
    ParentName = SUBSTRING(maxParentDetailsForMax,10,8000)

试试这样的东西??第一个 CTE 将为每个 ChildID 获得 Max(match_per)。然后,第二个将使用新的 MaxMatchPer 来查找其对应的 ParentID 应该是什么。

; WITH CTE AS (
    SELECT ChildID,MAX(match_per) AS MaxMatchPer
    FROM tbl
    GROUP BY ChildID
), CTE1 AS (
    SELECT t.ParentID, c.ChildID
    FROM tbl t
    JOIN CTE c
        ON c.ChildID = t.ChildID
        AND c.MaxMatchPer = t.match_per
)
UPDATE t
SET ParentID = c.ParentID
FROM tbl t
LEFT JOIN CTE1 c
    ON c.ChildID = t.ChildID

另外,这是很差的归一化。您不应在此 table 中包含 ParentName 或 ChildName。

获取父 ID 和父名称有点棘手。我认为逻辑最简单使用 cross apply:

with toupdate as (
      select t.*, p.parentId as new_parentId, p.parentName as new_parentName
             max(match_per) over (partition by childid) as max_match_per,
             count(*) over (partition by childid) as numparents
      from table t cross apply 
           (select top 1 p.*
            from table p
            where p.childid = t.childid
            order by match_per desc
           ) p
     )
update toupdate
    set parentId = new_ParentId,
        parentName = new_ParentName
    where numparents > 1;

注意:父 ID 和父名称都存储在 table 中,这可能是一个问题。我希望根据 ID 查找名称,以减少数据冗余。