最近项目新需求,原表不满足现有的业务,需要增加字段,增加字段会涉及到历史数据的校正,之前没遇到过类似的情况,记录下过程
表结构
id | foreignkey | createtime | num |
---|---|---|---|
1 | 1 | 2022-02-18 12:12:12 | null |
2 | 1 | 2022-02-17 12:12:12 | null |
3 | 1 | 2022-02-16 12:12:12 | null |
4 | 1 | 2022-02-15 12:12:12 | null |
5 | 2 | 2022-02-18 12:12:12 | 4 |
6 | 2 | 2022-02-17 12:12:12 | 3 |
7 | 2 | 2022-02-16 12:12:12 | 2 |
8 | 2 | 2022-02-15 12:12:12 | 1 |
需求,按照同一外键设置num的值,要和创建时间升序保持一致
如foreignkey等于2时 num的值
实现过程
错误写法
--错误原因:同一事务中无法更新到原表,子查询也不能实时读取
update table t1
set num = (select count(t2.id) from table t2 where t1.foreignkey = t2.foreignkey and num is null);
正确写法
--但是这个sql也会存在一个问题,每执行一条数据都会生成一张临时表,效率特别低
update table t1
set num = (select count(t2.id) from table t2 where t1.foreignkey = t2.foreignkey and t2.createtime <= t2.createtime);
最终写法
--这种是进行分组后排序,再生成组内行号,from后面只会生成一张临时表,效率相对来说比较高
update table t2
set num = t1.rn
from (
select
id,
foreignkey,
row_number() over(partition by foreignkey order by createtime ASC) rn
from table
) t1
where t1.id = t2.id;