提取位置
题目 提取1的位置
create table position_1(
a varchar(7) comment '含1的字符串'
) comment '1的位置';
insert into position_1
values ('1011'),('0101');
解决 字符串拆成数组
with tmp as(-- 1.字符串添加分隔符
select
a,
concat_ws('-',substring(a,1,1),substring(a,2,1),substring(a,3,1),substring(a,4,1)) a1
from position_1
)
select -- 3.posexplode 位置
a,a1, -- Hive不能直接访问非group by字段
concat_ws('-',collect_list(cast(pos + 1 as string))) pos_1
from tmp -- UDAF包围可以访问
lateral view posexplode(split(a1,'-')) pes as pos,val -- 2.字符串拆成数组
where val = 1
group by a,a1;
题目 成对提取
两列对应位置元素
create table paired_extraction(
a string comment '字母和/',
b string comment '数字和/'
) comment '成对地提取';
insert into paired_extraction
values ('A/B','1/3'),('B/C/D','4/5/2');
解决1 posexplode 位置相等
select -- 输出格式 多种
a,b,
concat_ws('/',collect_list(concat(val_a,':',val_b))) kv,
collect_list(concat(val_a,':',val_b))[0] kv_0,
collect_list(concat(val_a,':',val_b))[1] kv_1,
collect_list(concat(val_a,':',val_b))[2] kv_2
from paired_extraction -- 两次追加的数据 关联范围笛卡尔积 追加第三次数据
lateral view posexplode(split(a,'/')) pes_a as pos_a,val_a -- 辅助扩展表数据 源表追加第一次数据
lateral view posexplode(split(b,'/')) pes_b as pos_b,val_b -- 源表追加第二次数据
where pos_a = pos_b
group by a,b;
解决2 数组下标
select
a,b,
concat(split(a,'/')[0],'-',split(b,'/')[0]) ab, -- 下标一一对应
concat(split(a,'/')[1],'-',split(b,'/')[1]) ab1,
concat(split(a,'/')[2],'-',split(b,'/')[2]) ab2
from paired_extraction;
解决3 explode+排名+交叉连接
with tmp as(-- explode + 排名 = posexplode
select a,b,val_a,row_number() over(partition by a,b) rn_a
from paired_extraction
lateral view explode(split(a,'/')) ex_a as val_a
),
tmp1 as(
select a,b,val_b,row_number() over(partition by a,b) rn_b
from paired_extraction
lateral view explode(split(b,'/')) ex_b as val_b
)
select
tmp.a,tmp.b,concat_ws('/',collect_list(concat(val_a,'-',val_b))) ab
from tmp,tmp1 -- 交叉连接 = lateral view 炸裂函数
where tmp.a = tmp1.a and rn_a = rn_b
group by tmp.a,tmp.b;