SQL Server 2008中如何合并两个表并更新匹配的目标行?
常见疑问先明确
- VARCHAR类型完全可以作为连接匹配条件,只要两个表的Section字段类型、长度、排序规则一致即可,你当前的场景用月份名称作为匹配键完全合理。
- LEFT JOIN可以解决你的需求,核心是取值时优先取辅助表
@aux的数值,没有匹配的再保留基础表@Base的原始值。
方案1:直接查询得到目标结果(不修改原表)
用LEFT JOIN加COALESCE函数实现,COALESCE会返回第一个非空的参数值,刚好匹配你优先用@aux数值的需求:
SELECT COALESCE(a.Total, b.Total) AS Total, b.Section, COALESCE(a.EsConCita, b.EsConCita) AS EsConCita, COALESCE(a.EsAnticipada, b.EsAnticipada) AS EsAnticipada, COALESCE(a.EsAtrasada, b.EsAtrasada) AS EsAtrasada FROM @Base b LEFT JOIN @aux a ON b.Section = a.Section
方案2:直接更新基础表@Base的数据
如果需要把修改同步到原基础表,用UPDATE关联查询即可,只会更新@aux里存在匹配的行:
UPDATE b SET b.Total = a.Total, b.EsConCita = a.EsConCita, b.EsAnticipada = a.EsAnticipada, b.EsAtrasada = a.EsAtrasada FROM @Base b INNER JOIN @aux a ON b.Section = a.Section -- 执行完后直接查询@Base就是目标结果 SELECT * FROM @Base
附:EXISTS写法参考
你困惑的EXISTS关键字在这里的作用是判断@aux中是否存在对应匹配行,只有匹配成功才执行更新,写法如下:
UPDATE b SET Total = (SELECT Total FROM @aux a WHERE a.Section = b.Section), EsConCita = (SELECT EsConCita FROM @aux a WHERE a.Section = b.Section), EsAnticipada = (SELECT EsAnticipada FROM @aux a WHERE a.Section = b.Section), EsAtrasada = (SELECT EsAtrasada FROM @aux a WHERE a.Section = b.Section) FROM @Base b WHERE EXISTS ( SELECT 1 FROM @aux a WHERE a.Section = b.Section )
以上所有方案执行后得到的结果都和你期望的输出完全一致。
内容的提问来源于stack exchange,提问作者ivacon
相关产品推荐
相关产品推荐

