B表批量更新A表,A表记录不存在则插入新记录

zl_c 2013-05-30 01:37:32
A表
------------------
id total
1 100.00
2 50.00
3 320.00

B表
-------------------
id price
1 10.00
3 18.00
4 15.00

现需要将B表price加到A表的对应ID的total里去,如果A表没有这个ID,则在A表插入新ID记录且将prize保存到total字段。希望能用一句SQL实现。

update Atable A set total=total+B.price from BTable B where A.id=B.id--这只更新了A表中已有的ID。


希望最后A表的结果是:
------------------
id total
1 110.00
2 50.00
3 338.00
4 15.00
...全文
240 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
MrYangkang 2013-05-30
  • 打赏
  • 举报
回复
引用 11 楼 zl_c 的回复:
[quote=引用 10 楼 ZaoLianBuXiQi 的回复:] [quote=引用 9 楼 zl_c 的回复:] 是不是应该先update?先insert, ID=4 这条就变30了。
你多执行了一次的原因吗,正常是不可能呀 UPDATE 只更新有的,insert 只插人没有的,你先确认下[/quote] 先插入的话,a表就会有了ID=4 total=15的记录了。然后再更新,会在ID=4这条上再加上15.变30了。[/quote] 你说的是对的

--查询
select isnull(a.id,b.id)id,isnull(total,0)+isnull(B.price,0)total from a full join b on a.id = b.id
go
select * from a
go
--修改
update A set total=isnull(total,0)+isnull(B.price,0) from B where A.id=B.id
go
with t as
(
select isnull(a.id,b.id)id,isnull(B.price,0)price from a full join b on a.id = b.id
)
,t1 as
(
 select t.id,t.price from t left join a on t.id = a.id where a.id is null
)
insert into a select id,price from t1
go
select * from a
zl_c 2013-05-30
  • 打赏
  • 举报
回复
用not in写了一条,不知道效率是不是很差啊。
--修改
update a set total=total+b.price from b where a.id=b.id
go
insert a select id,price from b where id not in(select id from a)
go
select * from a
zl_c 2013-05-30
  • 打赏
  • 举报
回复
引用 10 楼 ZaoLianBuXiQi 的回复:
[quote=引用 9 楼 zl_c 的回复:] 是不是应该先update?先insert, ID=4 这条就变30了。
你多执行了一次的原因吗,正常是不可能呀 UPDATE 只更新有的,insert 只插人没有的,你先确认下[/quote] 先插入的话,a表就会有了ID=4 total=15的记录了。然后再更新,会在ID=4这条上再加上15.变30了。
MrYangkang 2013-05-30
  • 打赏
  • 举报
回复
引用 9 楼 zl_c 的回复:
[quote=引用 7 楼 ZaoLianBuXiQi 的回复:]

--修改
with t as
(
select isnull(a.id,b.id)id,isnull(B.price,0)price from a full join b on a.id = b.id
)
,t1 as
(
 select t.id,t.price from t left join a on t.id = a.id where a.id is null
)
insert into a select id,price from t1
go
update A set total=total+B.price from B where A.id=B.id
go
select * from a
是不是应该先update?先insert, ID=4 这条就变30了。[/quote] 你多执行了一次的原因吗,正常是不可能呀 UPDATE 只更新有的,insert 只插人没有的,你先确认下
zl_c 2013-05-30
  • 打赏
  • 举报
回复
引用 7 楼 ZaoLianBuXiQi 的回复:

--修改
with t as
(
select isnull(a.id,b.id)id,isnull(B.price,0)price from a full join b on a.id = b.id
)
,t1 as
(
 select t.id,t.price from t left join a on t.id = a.id where a.id is null
)
insert into a select id,price from t1
go
update A set total=total+B.price from B where A.id=B.id
go
select * from a
是不是应该先update?先insert, ID=4 这条就变30了。
zl_c 2013-05-30
  • 打赏
  • 举报
回复
引用 4 楼 TravyLee 的回复:
--------------------------------------------------------------------------
再者可以通过存储过程的if  判断来实现
如何在存储过程中实现?用update Atable A set total=total+B.price from BTable B where A.id=B.id可以更新两表都有的记录。B表剩下的记录如何入A表呢?难道用not in吗?
MrYangkang 2013-05-30
  • 打赏
  • 举报
回复

if object_id('a') is not null
drop table a
go
create table a
(
	id int,
	total float
)
go
if object_id('b') is not null
drop table b
go
create table b
(
	id int,
	price float
)
go
insert into a
select 1,100 union all
select 2,50 union all
select 3,320
go
insert into b
select 1,10 union all
select 3,18 union all
select 4,15

go
--查询
select isnull(a.id,b.id)id,isnull(total,0)+isnull(B.price,0)total from a full join b on a.id = b.id
go
select * from a
go
--修改
with t as
(
select isnull(a.id,b.id)id,isnull(B.price,0)price from a full join b on a.id = b.id
)
,t1 as
(
 select t.id,t.price from t left join a on t.id = a.id where a.id is null
)
insert into a select id,price from t1
go
update A set total=total+B.price from B where A.id=B.id
go
select * from a
zl_c 2013-05-30
  • 打赏
  • 举报
回复
引用 1 楼 SmithLiu328 的回复:
如果是2008的话可以尝试MERGE语法 http://www.cnblogs.com/CareySon/archive/2012/03/07/2383690.html
是MSSQL2005
MrYangkang 2013-05-30
  • 打赏
  • 举报
回复

if object_id('a') is not null
drop table a
go
create table a
(
	id int,
	total float
)
go
if object_id('b') is not null
drop table b
go
create table b
(
	id int,
	price float
)
go
insert into a
select 1,100 union all
select 2,50 union all
select 3,320
go
insert into b
select 1,10 union all
select 3,18 union all
select 4,15

go
select isnull(a.id,b.id)id,isnull(total,0)+isnull(B.price,0)total from a full join b on a.id = b.id
  • 打赏
  • 举报
回复
--------------------------------------------------------------------------

--  Author : htl258(Tony)

--  Date   : 2010-04-25 01:10:28

--  Version:Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) 

--          Jul  9 2008 14:43:38 

--          Copyright (c) 1988-2008 Microsoft Corporation

--          Developer Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)

--  Blog   : http://blog.csdn.net/htl258

--  Subject: SQL2008 Merge关键字用法与简例

--------------------------------------------------------------------------

--Merge 语法是对表进行插入,更新,删除这三个操作的合并。

--根据与源表联接的结果,对目标表执行插入、更新或删除操作。

--MERGE 语法包括如下五个主要子句:

--  MERGE 子句用于指定作为插入、更新或删除操作目标的表或视图。

--  USING 子句用于指定要与目标联接的数据源。

--  ON 子句用于指定决定目标与源的匹配位置的联接条件。

--  WHEN 子句用于根据ON 子句的结果指定要执行的操作。

--  OUTPUT 子句针对更新、插入或删除的目标对象中的每一行返回一行。

 

 

--示例:

 

USE tempdb

GO

--创建表A

IF NOT OBJECT_ID('[A]') IS NULL

    DROP TABLE [A]

GO

CREATE TABLE A(ID INT,ACOL VARCHAR(10))

GO

INSERT A VALUES(1,N'A')

INSERT A VALUES(2,N'B')

INSERT A VALUES(3,N'C')

INSERT A VALUES(6,N'X') --此记录在B表中不存在,删除

GO

--创建表B

IF NOT OBJECT_ID('[B]') IS NULL

    DROP TABLE [B]

GO

CREATE TABLE B(ID INT,BCOL VARCHAR(10),XCOL VARCHAR(10))

GO

INSERT B VALUES(1,N'A',N'T')  --1的ID与A表ID匹配且指定值与A表指定值对应相同,不变

INSERT B VALUES(2,N'P',N'O')  --2和的ID与A表ID匹配,指定值与A表指定值对应不同,更新

INSERT B VALUES(3,N'P',N'N')

INSERT B VALUES(4,N'L',N'Y')  --4和的ID与A表ID匹配,指定值在A表中对应不存在,插入

INSERT B VALUES(5,N'E',N'S')  

GO

--开始合并两个表:

MERGE A --要处理的表

USING B --参照的表

ON A.ID=B.ID --关联条件

WHEN NOT MATCHED THEN INSERT VALUES(B.ID,B.BCOL) --如果要处理表没有参照表上的记录,则插入

WHEN MATCHED THEN UPDATE SET A.ACOL=B.BCOL --如果记录匹配,就更新目标表的匹配行

WHEN NOT MATCHED BY SOURCE THEN DELETE --如果要处理表的记录在参照表上不存在,则删除

OUTPUT $action, Inserted.*, Deleted.*; --相当于输出以上语句的操作记录

 

/*--result:

$action    ID          ACOL       ID          ACOL

---------- ----------- ---------- ----------- ----------

INSERT     4           L          NULL        NULL

INSERT     5           E          NULL        NULL

UPDATE     1           A          1           A

UPDATE     2           P          2           B

UPDATE     3           P          3           C

DELETE     NULL        NULL       6           X

 

(6 行受影响)

*/

--看看A表更新成什么样:

SELECT * FROM A

/*

ID          ACOL

----------- ----------

1           A

2           P

3           P

4           L

5           E

 

(5 行受影响)

*/

--再变换一个字段

MERGE A --要处理的表

USING B --参照的表

ON A.ID=B.ID --关联条件

WHEN NOT MATCHED THEN INSERT VALUES(B.ID,B.XCOL) 

WHEN MATCHED THEN UPDATE SET A.ACOL=B.XCOL 

WHEN NOT MATCHED BY SOURCE THEN DELETE

OUTPUT $action, Inserted.*, Deleted.*;

 

/*--result:

$action    ID          ACOL       ID          ACOL

---------- ----------- ---------- ----------- ----------

UPDATE     1           T          1           A

UPDATE     2           O          2           P

UPDATE     3           N          3           P

UPDATE     4           Y          4           L

UPDATE     5           S          5           E

 

(5 行受影响)

*/

--再看看现在的A表像什么样

SELECT * FROM A

/*

ID          ACOL

----------- ----------

1           T

2           O

3           N

4           Y

5           S
(5 行受影响)

*/


 



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/htl258/archive/2010/04/25/5525814.aspx


再者可以通过存储过程的if  判断来实现
zhangzhen_927116 2013-05-30
  • 打赏
  • 举报
回复
先检测再更新,笨办法。
-Tracy-McGrady- 2013-05-30
  • 打赏
  • 举报
回复
case when then 能不能实现?多写点嘛,干嘛就一句
KevinLiu 2013-05-30
  • 打赏
  • 举报
回复
如果是2008的话可以尝试MERGE语法 http://www.cnblogs.com/CareySon/archive/2012/03/07/2383690.html

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧