需求
原始数据
|
year
|
tag
|
|
2014
|
1
|
|
2015
|
1
|
|
2016
|
0
|
|
2017
|
0
|
|
2018
|
0
|
|
2020
|
1
|
|
2021
|
1
|
|
2022
|
1
|
结果数据
|
2014
|
1
|
1
|
|
2015
|
1
|
2
|
|
2016
|
0
|
1
|
|
2017
|
0
|
2
|
|
2018
|
0
|
3
|
|
2020
|
1
|
1
|
|
2021
|
1
|
2
|
|
2022
|
1
|
3
|
说明:字段1是有序的,按照字段2分块计数,每当字段2变化,就重新开始计数,计数的结果当作字段3返回
数据准备
create table temp_block_sort_0309
(
year int,
tag int
) stored as orc
tblproperties ('orc.compress' = 'snappy');
insert into temp_block_sort_0309
values (2014, 1),
(2015, 1),
(2016, 0),
(2017, 0),
(2018, 0),
(2020, 1),
(2021, 1),
(2022, 1);
select * from temp_block_sort_0309;
解题方案
解决这个问题可以分 3 步走
1、判定当前行和上一行的第二列是否相等,如果不等置为1,相等为0,作为flag列
select *, case when lag(tag, 1) over (order by year) != tag then 1 else 0 end as flag
from temp_block_sort_0309;
|
year
|
tag
|
flag
|
|
2014
|
1
|
0
|
|
2015
|
1
|
0
|
|
2016
|
0
|
1
|
|
2017
|
0
|
0
|
|
2018
|
0
|
0
|
|
2020
|
1
|
1
|
|
2021
|
1
|
0
|
|
2022
|
1
|
0
|
2、对 flag列进行累加,值作为分桶id
select *, sum(flag) over (order by year) tong_id
from (select *, case when lag(tag, 1) over (order by year) != tag then 1 else 0 end as flag
from temp_block_sort_0309) t;
|
year
|
tag
|
flag
|
tong_id
|
|
2014
|
1
|
0
|
0
|
|
2015
|
1
|
0
|
0
|
|
2016
|
0
|
1
|
1
|
|
2017
|
0
|
0
|
1
|
|
2018
|
0
|
0
|
1
|
|
2020
|
1
|
1
|
2
|
|
2021
|
1
|
0
|
2
|
|
2022
|
1
|
0
|
2
|
3、按照累加的值(分桶id)分组 & 组内重排序
select year, tag, row_number() over (partition by tong_id order by year) js_id, flag
from (select *, sum(flag) over (order by year) tong_id
from (select *, case when lag(tag, 1) over (order by year) != tag then 1 else 0 end as flag
from temp_block_sort_0309) t) t
order by 1;
|
year
|
tag
|
js_id
|
flag_id
|
|
2014
|
1
|
1
|
0
|
|
2015
|
1
|
2
|
0
|
|
2016
|
0
|
1
|
1
|
|
2017
|
0
|
2
|
0
|
|
2018
|
0
|
3
|
0
|
|
2020
|
1
|
1
|
1
|
|
2021
|
1
|
2
|
0
|
|
2022
|
1
|
3
|
0
|