求一高效率的更新

jyh070207 2011-09-16 10:49:44
由于需要更新的数据量很大,需要有效率
根据示例数据要求,根据#t2表的code及dt检查,
如果在#t1表没有对应的code及dt,则将#t1表的amount改为0,
如有对应的code及dt而且#t2.amount > #t1.amount 则将#t1.amount 改为#t2.amount,
小于的不改
注意,在#t1同一code及dt可能有多条amount不同的记录存在,
#t2中,code+dt唯一
示例数据如下:
create table #t1(id int identity,code varchar(10),dt datetime,amount int)
insert into #t1(code,dt,amount)
select 'a01','2011-09-15',20
union all
select 'a01','2011-09-15',10
union all
select 'a01','2011-09-12',2
union all
select 'a01','2011-09-14',15
union all
select 'a01','2011-09-14',30
union all
select 'a02','2011-09-12',2
union all
select 'a02','2011-09-14',15
union all
select 'a02','2011-09-14',30

create table #t2(id int identity,code varchar(10),dt datetime,amount int)
insert into #t2(code,dt,amount)
select 'a01','2011-09-15',15
union all
select 'a01','2011-09-16',2
union all
select 'a01','2011-09-14',18
union
select 'a02','2011-09-14',20


更新后#t1的资料应为
select code,dt,amount from #t1
code dt amount
a01 2011-09-15 15--此处将20改为15,因在#t2中,code=a01 and dt = 2011-09-15的amount = 15
a01 2011-09-15 10--这个不改,因10<15
a01 2011-09-12 0--此处将2改为0,因在#t2中,没有对应的code 及dt
a01 2011-09-14 15--这个不改
a01 2011-09-14 18--此处将30改为18
a02 2011-09-12 0--此处将2改为0,因在#t2中,没有对应的code 及dt
a02 2011-09-14 15--这个不改
a02 2011-09-14 20--此处将30改为20


...全文
90 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
jyh070207 2011-09-16
  • 打赏
  • 举报
回复
谢谢各位!
wynlc 2011-09-16
  • 打赏
  • 举报
回复
学习一下
--小F-- 2011-09-16
  • 打赏
  • 举报
回复
update
a
set
amount=case when b.code is null then 0
when b.amount<a.amount then b.amount else a.amount end
from
t1 a ,t2 b
where
a.code=b.code
and
a.dt=b.dt
dawugui 2011-09-16
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 jyh070207 的回复:]
是说反了,
如有对应的code及dt而且#t2.amount <= #t1.amount 则将#t1.amount 改为#t2.amount,
大于的不改
注意,在#t1同一code及dt可能有多条amount不同的记录存在,
[/Quote]
update #t1 set amount = t2.amount from #t1 t1 , #t2 t2 where  t2.code = t1.code and t2.dt = t1.dt and t2.amount < t1.amount 
update #t1 set amount = 0 from #t1 t1 where not exists(select 1 from #t2 t2 where t2.code = t1.code and t2.dt = t1.dt)

select * from #t1
/*

id code dt amount
----------- ---------- ------------------------------------------------------ -----------
1 a01 2011-09-15 00:00:00.000 15
2 a01 2011-09-15 00:00:00.000 10
3 a01 2011-09-12 00:00:00.000 0
4 a01 2011-09-14 00:00:00.000 15
5 a01 2011-09-14 00:00:00.000 18
6 a02 2011-09-12 00:00:00.000 0
7 a02 2011-09-14 00:00:00.000 15
8 a02 2011-09-14 00:00:00.000 20

(所影响的行数为 8 行)

*/
-晴天 2011-09-16
  • 打赏
  • 举报
回复
写成一条:
create table #t1(id int identity,code varchar(10),dt datetime,amount int)
insert into #t1(code,dt,amount)
select 'a01','2011-09-15',20 union all
select 'a01','2011-09-15',10 union all
select 'a01','2011-09-12',2 union all
select 'a01','2011-09-14',15 union all
select 'a01','2011-09-14',30 union all
select 'a02','2011-09-12',2 union all
select 'a02','2011-09-14',15 union all
select 'a02','2011-09-14',30
create table #t2(id int identity,code varchar(10),dt datetime,amount int)
insert into #t2(code,dt,amount)
select 'a01','2011-09-15',15 union all
select 'a01','2011-09-16',2 union all
select 'a01','2011-09-14',18 union all
select 'a02','2011-09-14',20
go
update t set amount=(case when b.amount>t.amount then t.amount when b.amount is null then 0 else b.amount end)
from #t1 t left join #t2 b on t.code=b.code and t.dt=b.dt-- and b.amount<t.amount

select * from #t1
/*
id code dt amount
----------- ---------- ----------------------- -----------
1 a01 2011-09-15 00:00:00.000 15
2 a01 2011-09-15 00:00:00.000 10
3 a01 2011-09-12 00:00:00.000 0
4 a01 2011-09-14 00:00:00.000 15
5 a01 2011-09-14 00:00:00.000 18
6 a02 2011-09-12 00:00:00.000 0
7 a02 2011-09-14 00:00:00.000 15
8 a02 2011-09-14 00:00:00.000 20

(8 行受影响)
*/

go
drop table #t1,#t2
dawugui 2011-09-16
  • 打赏
  • 举报
回复
update #t1 set amount = t2.amount from #t1 t1 , #t2 t2 where  t2.code = t1.code and t2.dt = t1.dt and t2.amount > t1.amount 
update #t1 set amount = 0 from #t1 t1 where not exists(select 1 from #t2 t2 where t2.code = t1.code and t2.dt = t1.dt)

select * from #t1

/*

id code dt amount
----------- ---------- ------------------------------------------------------ -----------
1 a01 2011-09-15 00:00:00.000 20
2 a01 2011-09-15 00:00:00.000 15
3 a01 2011-09-12 00:00:00.000 0
4 a01 2011-09-14 00:00:00.000 18
5 a01 2011-09-14 00:00:00.000 30
6 a02 2011-09-12 00:00:00.000 0
7 a02 2011-09-14 00:00:00.000 20
8 a02 2011-09-14 00:00:00.000 30

(所影响的行数为 8 行)

*/
苏州牛恋歌 2011-09-16
  • 打赏
  • 举报
回复
2楼正解啊!
-晴天 2011-09-16
  • 打赏
  • 举报
回复
create table #t1(id int identity,code varchar(10),dt datetime,amount int)
insert into #t1(code,dt,amount)
select 'a01','2011-09-15',20 union all
select 'a01','2011-09-15',10 union all
select 'a01','2011-09-12',2 union all
select 'a01','2011-09-14',15 union all
select 'a01','2011-09-14',30 union all
select 'a02','2011-09-12',2 union all
select 'a02','2011-09-14',15 union all
select 'a02','2011-09-14',30
create table #t2(id int identity,code varchar(10),dt datetime,amount int)
insert into #t2(code,dt,amount)
select 'a01','2011-09-15',15 union all
select 'a01','2011-09-16',2 union all
select 'a01','2011-09-14',18 union all
select 'a02','2011-09-14',20
go
update t set amount=b.amount from #t1 t inner join #t2 b on t.code=b.code and t.dt=b.dt and b.amount<t.amount
update t set amount=0 from #t1 t where not exists(select 1 from #t2 where code=t.code and dt=t.dt)
select * from #t1
/*
id code dt amount
----------- ---------- ----------------------- -----------
1 a01 2011-09-15 00:00:00.000 15
2 a01 2011-09-15 00:00:00.000 10
3 a01 2011-09-12 00:00:00.000 0
4 a01 2011-09-14 00:00:00.000 15
5 a01 2011-09-14 00:00:00.000 18
6 a02 2011-09-12 00:00:00.000 0
7 a02 2011-09-14 00:00:00.000 15
8 a02 2011-09-14 00:00:00.000 20

(8 行受影响)
*/

go
drop table #t1,#t2
jyh070207 2011-09-16
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 nbdba 的回复:]
说反了吧

如有对应的code及dt而且#t2.amount > #t1.amount 则将#t1.amount 改为#t2.amount,
小于的不改

a01 2011-09-15 15--此处将20改为15,因在#t2中,code=a01 and dt = 2011-09-15的amount = 15
a01 2011-09-15 10--这个不改,因10<15

这两段反了……
[/Quote]

是说反了,
如有对应的code及dt而且#t2.amount <= #t1.amount 则将#t1.amount 改为#t2.amount,
大于的不改
注意,在#t1同一code及dt可能有多条amount不同的记录存在,
NBDBA 2011-09-16
  • 打赏
  • 举报
回复
说反了吧

如有对应的code及dt而且#t2.amount > #t1.amount 则将#t1.amount 改为#t2.amount,
小于的不改

a01 2011-09-15 15--此处将20改为15,因在#t2中,code=a01 and dt = 2011-09-15的amount = 15
a01 2011-09-15 10--这个不改,因10<15

这两段反了,不知哪个为准,不过没关系,反了你就自己改回来

UPDATE T1 SET
amount = CASE WHEN T2.CODE IS NULL THEN 0
WHEN t2.amount < t1.amount THEN t2.amount
ELSE T1.amount
END
FROM #T1 T1 LEFT JOIN #T2 T2
ON T1.CODE = T2.CODE
AND T1.DT = T2.DT
geniuswjt 2011-09-16
  • 打赏
  • 举报
回复
瞟了一眼应该是case when,等会仔细看下
更新框架设计系列课程总体介绍:        本系列课程由《热更新框架设计之Xlua基础》、《热更新框架设计之热更流程与热补丁技术》、《热更新框架设计之游戏客户端框架》三套课程组成。 三套课程是一个不可分割有机的整体,笔者带领大家由浅入深逐级深入 ,领悟热更精髓的基础之上,通过高端架构设计设计出“低耦合”、“低侵入”、“高复用”性的游戏(VR/AR)客户端热更框架。《热更新框架设计之客户端热更框架》课程介绍:        本作是热更框架系列课程中的客户端框架设计与实现部分。理解本作需要之前的所有知识点积累,在其基础之上给学员展现当今商业热更框架中,商业级热更框架的基本原理、设计全过程、实现框架产品等全过程。通过本作学习可以让资深开发人员晋升为游戏架构师、主程、技术总监等职位。        为了更好更快的服务广大学员,本课程分为上、中、下三部分,内容如下:        上部:               UI框架与AB框架整合,重构整合为 “热更新UI框架”。        中部:            “热更新UI框架”与热更流程技术重构整合。              纯Lua框架设计理念与实现。        下部:               复合型热更框架设计与实现。               框架产品加入HotFix功能模块,且功能演示与测试完善。《热更新框架设计之客户端热更框架(中部)》课程介绍:        热更客户端中部,主要就两大部分进行讲解:        第一部分:  “热更新UI框架”与热更流程技术重构整合         这部分“热更新流程实现脚本”与之前的UI框架、AB框架进行无缝的重构与整合进行开发。         这里涉及到很多地方的重构与处理:         1: Unity编辑器脚本中的创建校验文件、拷贝资源文件等的重构。         2: 由于单机版本框架所使用的Resources 目录被彻底取消,所以整个框架中,凡是涉及到Resources的编码部分,均要进行深入加工与修改,例如: ConfigManagerByJson.cs、UIManager.cs、SysDefine、Log、LauguageMgr等。        第二部分: “纯lua框架”整体设计与实现:        本部分是中部课程的核心,也是整个热更新框架的核心部分!        我们需要对商业项目中,业务功能面临经常频繁改动的部分,设计一套可复用、灵活、可扩展、高效率执行的lua框架系统。本框架系统,我们整体考虑采用类似MVC的“分层”结构进行整体架构设计,然后配之以Xlua技术,实现C#脚本与同名lua脚本之间的一对一映射关系。 这样可以使得每个3D/2D的预设对象,自动映射(预设)同名的一个lua控制脚本与一个“lua显示”脚本。        这里的“lua控制”脚本负责加载从服务器端传来的AB(AssetBundle)包资源,以及解析与显示AB包中的资源预设等。这些均为玩家所看不到的部分,所以都定义在控制层的lua脚本中。       对于需要显示的3D/2D 预设资源,我们使用“lua显示”脚本,控制显示的方式、内容与行为(包含事件注册)等。而本部分我们采用了xlua的映射技术,也使得“lua显示”脚本具备了Unity的常用生命周期函数,进一步大大简化了lua编写业务的难度,例如常见的:Awake()、Start()、Update()、OnDestroy()等。具体lua的架构设计如下图所示:           温馨提示:         1: 本套课程需要具备一定的框架理解与驾驭能力,为了更好的理解本作,强烈推荐广大学员首先学完必要的前导课程:“UI客户端框架设计”、“AssetBundle 框架设计”、“lua基础与中级篇”、以及本课程热更新框架的前两部(Xlua基础、热更流程与热补丁)。         2: 本课程使用Unity2017版本讲解,但是本课程主要讲解开发思想与具体实现技术,所以对Unity版本不敏感。 学员使用后续的Unity2018/19/2020..... 等版本基本没有影响。一、热更新系列(技术含量:中高级):A:《lua热更新技术中级篇》https://edu.csdn.net/course/detail/27087B:《热更新框架设计之Xlua基础视频课程》https://edu.csdn.net/course/detail/27110C:《热更新框架设计之热更流程与热补丁技术》https://edu.csdn.net/course/detail/27118D:《热更新框架设计之客户端热更框架(上)》https://edu.csdn.net/course/detail/27132E:《热更新框架设计之客户端热更框架(中)》https://edu.csdn.net/course/detail/27135F:《热更新框架设计之客户端热更框架(下)》https://edu.csdn.net/course/detail/27136二:框架设计系列(技术含量:中级): A:《游戏UI界面框架设计系列视频课程》https://edu.csdn.net/course/detail/27142B:《Unity客户端框架设计PureMVC篇视频课程(上)》https://edu.csdn.net/course/detail/27172C:《Unity客户端框架设计PureMVC篇视频课程(下)》https://edu.csdn.net/course/detail/27173D:《AssetBundle框架设计_框架篇视频课程》https://edu.csdn.net/course/detail/27169三、Unity脚本从入门到精通(技术含量:初级)A:《C# For Unity系列之入门篇》https://edu.csdn.net/course/detail/4560B:《C# For Unity系列之基础篇》https://edu.csdn.net/course/detail/4595C: 《C# For Unity系列之中级篇》https://edu.csdn.net/course/detail/24422D:《C# For Unity系列之进阶篇》https://edu.csdn.net/course/detail/24465四、虚拟现实(VR)与增强现实(AR):(技术含量:初级)A:《虚拟现实之汽车仿真模拟系统 》https://edu.csdn.net/course/detail/26618五、Unity基础课程系列(技术含量:初级) A:《台球游戏与FlappyBirds—Unity快速入门系列视频课程(第1部)》 https://edu.csdn.net/course/detail/24643B:《太空射击与移动端发布技术-Unity快速入门系列视频课程(第2部)》https://edu.csdn.net/course/detail/24645 C:《Unity ECS(二) 小试牛刀》https://edu.csdn.net/course/detail/27096六、Unity ARPG课程(技术含量:初中级):A:《MMOARPG地下守护神_单机版实战视频课程(上部)》https://edu.csdn.net/course/detail/24965B:《MMOARPG地下守护神_单机版实战视频课程(中部)》https://edu.csdn.net/course/detail/24968C:《MMOARPG地下守护神_单机版实战视频课程(下部)》https://edu.csdn.net/course/detail/24979

34,575

社区成员

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

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