2014-11-24 92 views
2

我试图从另一个表中更新表列。将多个行值更新到同一行和不同列

Person Table

person表,可以存在多个联系人具有相同inst_id

我有一个firm表,它将从person表中获得最新的2个联系方式。

我期待的firm表如下:

Firm Table

如果只有一个联系人,更新person1email1。如果有2个,则同时更新。如果有3个,则丢弃第3个。

有人可以帮助我吗?

+0

你是什么意思:*最新的2联系人详细信息*? – 2014-11-24 10:03:13

+0

顶2将罚款。 (具有最高的ID)。 – Sarin 2014-11-24 10:05:16

+0

你使用MySQL或SQL Server(如tsql标签所示)? – jpw 2014-11-24 10:20:20

回答

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 

用作在人表更新数的行的源极,通过INST_ID划分的公用表表达式(CTE),然后将更新加入CTE两次(对于顶部1和顶部2)。

Sample SQL Fiddle

+0

谢谢,这工作。 – Sarin 2014-11-24 10:49:43

0

我觉得你不必费心自己与此更新,如果你重新考虑你的数据库结构。关系数据库的一个重要优点是,你不需要在多个表中存储多次相同的数据,但是对于一种数据有一个单独的表(比如你的案例中的人的表),然后引用它(通过例如关系或外键)。

那么这对你的例子意味着什么?我建议,创建一个机构的表格,在其中插入contactperson1和contactperson2两个属性:但不要插入所有联系人详细信息(如电子邮件和姓名),只是人的主键并将其设置为外键。

所以,你有一个表“人”,这应该是这个样子:

ID INSTITUTION_ID NAME  EMAIL 
1  100   abc [email protected] 
2  101   efg [email protected] 
3  101   ijk [email protected] 
4  101   rtw [email protected] 
... 

和一张桌子“机构”,如:

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) 

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

+0

感谢您的建议。但是,该公司实际上是一个巨大的遗留表格。 我只创建了人员表格,我的要求是用新数据更新公司。 – Sarin 2014-11-24 11:54:21

相关问题