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

时间:2015-07-30 18:55:36

标签: sql sql-server sql-server-2008 sql-update row-number

我有一个表CUST,其布局如下。没有限制。我确实看到一个ChildID有多个ParentID与之关联。 (请参阅ChildID = 115

的记录

这是我需要的 -

如果一个孩子的父母不止一个,我想要使用ParentIDParentName更新ParentIDParentName,其中match_perParentID最多ParentName。因此,在下图中,我希望ChildId = 115 1111和match_per LEE YOUNG WOOK更新所有FileHandler fh = new FileHandler("C:/temp/test/MyLogFile.log"); 的记录(因为FileHandler fh = new FileHandler("C:/temp/test/MyLogFile.log", true); 0.96在给定集合中是最大值)。如果有两个父母具有相同的max match_per,那么我想选择其中任何一个。

Data Layout

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

3 个答案:

答案 0 :(得分:2)

一种方法

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)

答案 1 :(得分:1)

同时获取父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和父名都存储在表中的事实,可能多次似乎是一个问题。我希望在给定id的情况下查找名称,以减少数据冗余。

答案 2 :(得分:0)

尝试这样的事情?对于每个ChildID,第一个CTE将获得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

此外,这是不正常的标准化。您不应该在此表中包含ParentName和ChildName。