
工作中遇到的一个数据治理问题:治理出某地常住人口的地址变更内容,并按时间升序后合并展示。
举个例子,小明2019年住在A地,2020年搬到B地,2021年搬到C地,小华2019年住在E地,2021年住在F地,原始数据表(human_address)为
治理后的展示结果为
有兴趣的朋友可以先试试,不急着往后看解析。
解决思路为:
先利用row_number开窗函数按时间先后对地址进行排序,然后利用concat函数将序号和地址进行拼接,拼接后利用collect_set函数、sort_array函数和concat_ws函数进行排序合并,合并后再利用regexp_replace函数将多余的序号去掉。
有几个注意点需要提一下:
- rn字段为int类型,需要转换为string类型后才能用concat拼接。
- 为什么要对rn值为1,2,3…,9的前面加一个0呢,这是因为如果地址数量大于10,不加0的话,结果显示会有问题,比如有12个地址,在不去除序号时,显示的结果会是11M,12N,1A,2B……这并不是我们想要的。当然,就例子的数据不加0也是OK的。
- sort_array函数默认升序,如果要降序,需要将属性设为false。
- sort_array函数好像并不能按具体某字段进行排序,如果可以,sql代码就不用这么麻烦了。
- 去掉序号不能一步到位,先去掉最前面的序号,再去掉逗号后的序号。
具体实现代码如下:
select
name,
regexp_replace(
regexp_replace(
concat_ws(',',
sort_array(
collect_set(
concat(case when length(rn) = 1 then concat('0',cast(rn as string)) else cast(rn as string) end,detail_address_name)
)
)
)
,'^[0-9]*','')
,',[0-9]*',',') as address_change
from
(
select
name,
detail_address_name,
row_number() over(partition by name order by last_modification_time asc) as rn
from human_address
)a
group by name;
如果大佬有简单的方法可以实现,还望指点一二。
有任何问题也欢迎留言交流,互相学习,共同进步。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)