将多行值更新为同一行和不同列

时间:2014-11-24 09:45:40

标签: sql sql-server tsql sql-update

我试图从另一个表中更新表列。

Person Table

person表中,可能有多个联系人具有相同的inst_id

我有一个firm表,其中包含来自person表的最新2个联系人详细信息。

我期待firm表如下:

Firm Table

如果只有一位联系人,请更新person1email1。如果有2,则更新两者。如果有3,则丢弃第3个。

有人可以帮我吗?

2 个答案:

答案 0 :(得分:2)

这应该有效:

;with cte (rn, id, inst_id, person_name, email) as (
    select row_number() over (partition by inst_id order by id) rn, * 
    from person
    )

update f
set 
  person1 = cte1.person_name, 
  email1  = cte1.email, 
  person2 = cte2.person_name, 
  email2  = cte2.email
from firm f
left join cte cte1 on f.inst_id = cte1.inst_id and cte1.rn = 1
left join cte cte2 on f.inst_id = cte2.inst_id and cte2.rn = 2

公用表表达式(cte)用作person表中更新编号行的源,由inst_id分区,然后更新加入cte两次(对于前1和前2)。

Sample SQL Fiddle

答案 1 :(得分:0)

如果您重新考虑数据库结构,我认为您不必为此更新烦恼。关系数据库的一个很大的优点是,您不需要在多个表中多次存储相同的数据,但是对于一种数据(例如您的情况下的人员表)有一个单独的表,然后引用它(通过关系或外键,例如)。

那么这对你的例子意味着什么呢?我建议,创建一个机构的表,你插入两个属性,如contactperson1和contactperson2:但不要插入所有的联系方式(如电子邮件和名称),只是插入人的主键,并使其成为外键。

所以你有一个'人'表,看起来应该是这样的:

ID   INSTITUTION_ID   NAME      EMAIL
1        100          abc    abc@inst.com
2        101          efg    efg@xym.com
3        101          ijk    ijk@fg.com
4        101          rtw    rtw@rtw.com
... 

表格“机构”如:

ID   CONTACTPERSON1  CONTACTPERSON2
100        1             NULL
101        2              3
...

如果您现在想要更改电子邮件地址,只需更新此人的表格即可。您无需更新公司的表格。

您如何通过两位联系人的详细信息获得所需的“表格”?只需查询:

SELECT i.id, p1.name, p1.email, p2.name, p2.email
FROM institution i LEFT OUTER JOIN person p1 ON (i.contactperson1 = p1.id)
     LEFT OUTER JOIN person p2 ON (i.contactperson2 = p2.id)

如果您经常需要此查询并像“表格”那样访问它,只需将其存储为视图。