如何用SQL实现全量切片表转成拉链表

如何用SQL实现全量切片表转成拉链表
必须是写SQL的方式,不能用其他代码实现。
现有全量切片表样数据

切片日期主键编号状态
20211201A01
20211205A01
20220215A02
20220228A03
20220315A01
20220331A01
20220420A01
20220425A02
20220430A01
20211201B01
20211203B01
20220131B02

要一次性转换成拉链数据:要求不能用脚本重复循环跑SQL
转换成拉链表的数据为以下所示,30001231表示长期有效

主键编号开始日期状态结束日期
A202112010120220215
A202202150220220228
A202202280320220315
A202203150120220425
A202204250220220430
A202204300130001231
B202112010120220131
B202201310230001231

我现在主要问题是如何通过单纯的SQL,一次性进行转换。
若不是一次性,通过循环拉链算法脚本的话,我有样例:

--把每天跑批日期的切片数据按照拉链的形式插入到临时表中,表示当天新的拉链数据
INSERT INTO 临时表_当前
SELECT 
主键编号
,跑批日期
,状态
,'30001231'
FROM 切片表
WHERE 切片日期=跑批日期
;

--可以对当天进行重复跑批的操作
DELETE FROM 目标表
WHERE 开始日期='变量(跑批日期)'
AND 结束日期='30001231';
UPDATE 目标表
SET 结束日期='30001231'
WGERE 结束日期='变量(跑批日期)';

--找到与目标表中生效的数据不同的数据
INSERT INTO 临时表_插入
SELECT 
主键编号
,开始日期
,状态
.结束日期
FROM 临时表_当前
WHERE NOT EXISTS
(
SELECT 1
FROM  目标表 
WHERE 临时表_当前.主键编号=目标表.主键编号
AND 临时表_当前.状态=目标表.状态
AND 目标表.结束日期=30001231’
);

--更新目标表中的数据,对更新的数据进行关链
UPDATE 目标表
SET END_DT='跑批日期'
WHERE END_DT='30001231'
AND EXISTS
(SELECT 1
FROM 临时表_插入
WHERE 目标表.主键编号=临时表_插入.主键编号
);
--新增的数据插入目标表中
INSERT INTO 目标表
SELECT 
主键编号
,’跑批日期‘
,状态
,'30001231'
FROM 临时表_插入;

然后将以上的SQL,封装下,按照日期每天一次顺序跑批,也能完成切片转换成拉链的算法。
但是此方法碰到要处理10年的数据话,就要跑10年的每一日的批次,有点慢。
因此有大佬能一次性写个SQL,直接完成切片转换成拉链的么?

create table tmp_data_test2
(
ts string,
id string,
status string
);

insert into tmp_data_test2
values
('20211201','A','01'),
('20211205','A','01'),
('20220215','A','02'),
('20220228','A','03'),
('20220315','A','01'),
('20220331','A','01'),
('20220420','A','01'),
('20220425','A','02'),
('20220430','A','01'),
('20211201','B','01'),
('20211203','B','01'),
('20220131','B','02');

select
id,ts as start_date,status,
lead(ts,1,'30001231') over(partition by id order by ts) as end_date
from(
select
ts,id,status,
row_number() over(partition by id,status,group1 order by ts) as rank2
from(
select
ts,id,status,
floor(rank1-rank2) as group1
from(
select
ts,id,status,
row_number() over(partition by id order by ts) as rank1,
row_number() over(partition by id,status order by ts) as rank2
from tmp_data_test2
)t2
)t3
)t4
where rank2=1;
基于你给的样例数据,全量数据可以这样实现

单纯的sql一次性转换应该实现不了,正常的还是需要这种方法

全量表、增量表、拉链表如何生成?
https://blog.csdn.net/weixin_43648241/article/details/108961783