2015-07-30 3 views
0

У меня есть стол CUST со следующим расположением. Нет ограничений. Я вижу, что один ChildID имеет более одного связанного с ним связанного с ним ParentID. (Пожалуйста, смотрите записи для ChildID = 115)Как сделать условное обновление столбцов с помощью CTE?

Вот что мне нужно -

Где бы один ребенок имеет более чем 1 родитель, я хочу, чтобы обновить эти ParentID и ParentName с ParentID и ParentName, который имеет максимальную match_per. Итак, на рисунке ниже я хочу, чтобы ParentID 1111 и ParentName LEE YOUNG WOOK обновили все записи, где ChildId = 115 (так как match_per 0,96 максимум в пределах заданного набора). Если есть два родителя с равным max match_per, тогда я хочу выбрать один из них.

Data Layout

Я знаю, что это возможно с помощью КТР, но я не знаю, как обновить КТР. Может ли кто-нибудь помочь?

+0

Вместо 'SELECT * FROM myCTE' try' UPDATE myCTE SET myCTE.ParentName = 'Whatever' WHERE myCTE.YourColumn = 'somethingvalue'' – Fabio

ответ

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) 
0

Попробуйте что-то вроде этого ?? Первый CTE получит Max(match_per) для каждого ChildID. Затем второй будет использовать новый 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.

1

Получение и родительского идентификатора, и родительского имени несколько сложнее. Я думаю, что логика легче всего с помощью 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, чтобы уменьшить избыточность данных.

+0

Спасибо @Gordon за вашу помощь. Думаю, я поеду с ответом Мартина на этот вопрос. –

Смежные вопросы