SQL两列转多行_根据状态的开始时间和结束时间生成每月的状态表

文章描述了如何使用SQL查询处理产品状态表,通过状态变化时间计算每个产品每月的启用状态,包括停用到启用的时间间隔。涉及到分区、JOIN和LateralView等技术在数据处理中的应用。
摘要由CSDN通过智能技术生成

工作中,遇到这样一个需求:有一张产品状态表,记录每个产品的停用或启用状态以及状态发生变化的时间,需要统计每个月有多少在启用产品。
首先,根据状态变化的时间生成每个产品每个状态对应的开始时间和结束时间。

select product_id,status_desc,status_time,row_number() over(partition by product_id order by status_time) as rk
from dw.tableName
where status_desc = '已启用'
)t1
left join(
select product_id,status_desc,status_time,row_number() over(partition by product_id order by status_time) as rk
from dw.tableName
where status_desc = '已停用'
)t2
on t1.product_id=t2.product_id and t1.rk=t2.rk
where t2.product_id is not null

再根据产品启用和停用的时间间隔生成每月状态信息。

select product_id,start_status,substr(date_add(concat(start_date,'-','01'),idx),1,7) as ds
from(
select 
	t1.product_id,
	t1.status_desc start_status,
	t1.status_time start_date,
	t2.status_desc end_status, 
	t2.status_time end_date,
	int(months_between(concat(t2.status_time,'-','01'),concat(t1.status_time,'-','01'))) num_months
from(
select product_id,status_desc,status_time,row_number() over(partition by product_id order by status_time) as rk
from dw.tableName
where status_desc = '已启用'
)t1
left join(
select product_id,status_desc,status_time,row_number() over(partition by product_id order by status_time) as rk
from dw.tableName
where status_desc = '已停用'
)t2
on t1.product_id=t2.product_id and t1.rk=t2.rk
where t2.product_id is not null
and months_between(concat(t2.status_time,'-','01'),concat(t1.status_time,'-','01')) > 0
order by t1.product_id,start_date
)tmp
lateral view
posexplode(split(repeat('m_',num_months),'_')) temp as idx,x
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值