如何更新多行的1行?

时间:2018-04-11 13:36:29

标签: sql-server sql-update

编辑:这只是一个简单的例子,我知道它似乎非常错误,但我认为这是提出问题的最简单方法。

假设我有一个Person和一个'电子邮件'表。每个人可以有2封电子邮件。

这是一个小例子:

enter image description here

出于某种原因,我们决定将Person表扩展为2列:FirstEmailSecondEmail,因此在更新后,结果如下所示:

enter image description here

我可以用一个语句UPDATE表吗?例如,我试过这个,但它不起作用(不会出错,只有FirstEmail被填充,SecondEmailNULL)。

UPDATE Person
SET FirstEmail = CASE WHEN e.Type = 'FIRST' THEN e.Value ELSE FirstMail END,
    SecondMail = CASE WHEN e.Type = 'SECOND' THEN e.Value ELSE SecondMail END
FROM Person p
INNER JOIN Email e ON (p.Id = e.PersonId);

正如我所看到MERGE无法使用多行,因为我得到了类似方法的错误:

  

MERGE语句尝试多次更新或删除同一行。当目标行与多个源行匹配时会发生这种情况。 MERGE语句不能多次更新/删除目标表的同一行。优化ON子句以确保目标行最多匹配一个源行,或使用GROUP BY子句对源行进行分组。

3 个答案:

答案 0 :(得分:3)

以下查询应该适合您。

UPDATE P
SET P.FirstEmail = F.Value, 
    P.SecondEmail= S.Value
FROM Person P
INNER JOIN EMAIL F ON F.PersonId=P.ID AND F.TYPE='FIRST'
INNER JOIN EMAIL S ON S.PersonId=P.ID AND S.TYPE='SECOND'

如果您没有Person的电子邮件,那么您可以将INNER JOIN更改为LEFT JOIN

UPDATE P
SET P.FirstEmail = F.Value, 
    P.SecondEmail= S.Value
FROM Person P
LEFT JOIN EMAIL F ON F.PersonId=P.ID AND F.TYPE='FIRST'
LEFT JOIN EMAIL S ON S.PersonId=P.ID AND S.TYPE='SECOND'

答案 1 :(得分:2)

使用两个子查询,解决方案很简单:

update Person set
       FirstEMail = (select top 1 Value from EMail where PersonId = Person.Id and Type = 'FIRST'),
       SecondEMail = (select top 1 Value from EMail where PersonId = Person.Id and Type = 'SECOND')

答案 2 :(得分:0)

您的更新尝试的问题是,具有特定电子邮件的行永远不会是“第一”和“第二”(因此FirstEmail更新或SecondEmail是,但从不两者)。

解决方案是使用2个连接,每个电子邮件一个:

UPDATE P SET
    FirstEmail = E1.Value,
    SecondEmail = E2.Value
FROM
    Person AS P
    LEFT JOIN Email AS E1 ON
        E1.PersonID = P.ID AND
        E1.Type = 'First'
    LEFT JOIN Email AS E2 ON
        E2.PersonID = P.ID AND
        E2.Type = 'Second'