T-SQL更新连接1:N

时间:2016-04-13 04:41:43

标签: sql-server

我有两张桌子:

表1

id  fee1    fee2
1   0.00    0.00
2   0.00    0.00

表2

id  fee_no  fee
1   A       10.00
1   B       20.00
2   A       80.00
2   B       90.00

SQL:

update a
   set a.fee1 = isnull(a.fee1, 0)
              + (case when b.fee_no ='A'
                      then cast(isnull(b.fee, 0) as decimal(30, 2))
                      else 0 end),
       a.fee2 = isnull(a.fee2, 0)
              + (case when b.fee_no ='B'
                      then cast(isnull(b.fee, 0) as decimal(30,2))
                      else 0 end)
  from table1 a
 inner join table2 b on a.id = b.id

执行此SQL后,只更新fee1 table1,而fee2则不更新。最后,我使用两个SQL语句分别更新fee1fee2

但为什么这个SQL语句不起作用?

这是create table语句:

create table table1(
 id    int       null,
 fee1  dec(30,2) null,
 fee2  dec(30,2) null
)
insert into table1 (id,fee1,fee2)
select 1,0,0 union
select 2,0,0

create table table2(
 id       int         null,
 fee_no   varchar(10) null,
 fee      dec(30,2)   null
)
insert into table2 (id,fee_no,fee)
select 1,'A',10 union
select 1,'B',20 union
select 2,'A',80 union
select 2,'B',90 

1 个答案:

答案 0 :(得分:2)

您的查询存在的问题是table1的每一行都会更新两次。但是,当第二次更新发生时,它会对表的原始数据进行操作。因此,fee2会重新设置为0

要正确UPDATE,您需要这样的查询:

update a
   set a.fee1 = isnull(a.fee1, 0)
              + (case when b.fee_no ='A'
                      then cast(isnull(b.fee, 0) as decimal(30, 2))
                      else 0 end),
       a.fee2 = isnull(a.fee2, 0)
              + (case when c.fee_no ='B'
                      then cast(isnull(c.fee, 0) as decimal(30,2))
                      else 0 end)
 from table1 a
 inner join table2 b on a.id = b.id and b.fee_no = 'A'
 inner join table2 c on a.id = c.id and c.fee_no = 'B'