一个简单的批量更新oracle 数据库中 最近的服务商名称的数据
有一个需求是这样的,我们需要更新数据库中的数据,数据时这样的
1.大约50万以上
2. 数据中有较多的重复数据
3. 需要将表中最近的代理商的名称赋值给行中的服务商名称
4. 代理商的名称可能有多个,所以必须获取最近时间的代理商名称
5.对于客户代理商信息的确定必须使用客户主键,以及客户的软件加密狗的id
解决方案
1. 首先会想到
使用数据的遍历,获取客户PK 客户软件狗id 以及客户的代理商名称(最新的根据时间进行排序),进行数据的更新。
将代理商名称更新为服务商名称。
但是性能开销是很大的,同时运行的时间很慢。
这种方法被否决
2. 使用数据库提供的merge into
这种语法在oracle 9i 中才出现,比较庆幸使用的数据库刚好符合,
但是9i 的写法中必须有update 以及insert 这一点不太好 因为我们只想去更新,不用去插入
具体的解决方法如下:
1.创建一个理临时表 这张表的数据时复制需要更新的表的数据
使用的方式如下:
create table table__name as select * from Table_name
为了简单我只需要几个字段所以我同时获取了数据中分组之后的最近时间的数据
sql 代码如下:
select
a.CUSTOMER_PK,a.softdog ,a. agentname
from
(select CUSTOMER_PK,softdog,agentname ,rownum rid from testsoftdog1 order by saledate desc) a,
(select CUSTOMER_PK,softdog,agentname ,rownum rid from testsoftdog1 order by saledate desc) b
where
a.CUSTOMER_PK=b.CUSTOMER_PK and a.softdog=b.softdog and a.rid>=b.rid
group by
a.CUSTOMER_PK,a.softdog , a.agentname
having count(*)=1
为什么需要进行分组: 这个主要是我的业务数据的原因有重复的,因为客户主键 软件狗id 本来就可以确定用户的代理商数据,但是代理商数据是会变的,
同时数据库表中存储的数据时多行的,就是说同一客户id 以及软件狗id 可能是多条的数据,所以为了简单进行了数据的分组,以上就为获取最近代理商所有的信息的sql
对于数据的批量更新代码如下:
merge into testsoftdog2 t1
using ( select
a.CUSTOMER_PK,a.softdog ,a. agentname
from
(select CUSTOMER_PK,softdog,agentname ,rownum rid from testsoftdog1 order by saledate desc) a,
(select CUSTOMER_PK,softdog,agentname ,rownum rid from testsoftdog1 order by saledate desc) b
where
a.CUSTOMER_PK=b.CUSTOMER_PK and a.softdog=b.softdog and a.rid>=b.rid
group by
a.CUSTOMER_PK,a.softdog , a.agentname
having count(*)=1) t2
on (t1.CUSTOMER_PK=t2.CUSTOMER_PK and t1.softdog=t2.softdog)
when matched then
update
set
t1.SERVERAGAGENTNAME=t2.agentname;
when not matched then
insert
values(t2.CUSTOMER_PK,t2.softdog,t2.agentname)
红色部分就是我们使用的表的数据,后面就是数据的更新操作了,使用merge into
对于以上红色部分建议的使用方式是进行创建临时表数据。
使用上面的create 语句。
对于sql server 需要使用 select * into table__name from table_name
以上代码会高效的尽心数据的更新操作,相比遍历的方法快很多,
可能有人会有这样的疑问:为什么使用这种方式呢,你直接使用update 进行数据的更新不就行了吗,
主要是需要获取最新的代理商名称,而且客户的数据时多条的。