行转列、列转行在业务需求中相信很多开发的小伙伴不陌生了,老司机熟悉套路能轻车熟路巴拉巴拉完成开发,但对新手来说还是有一定难度。现在就分享个人开发过程的一些思路供大家参考。
首先说说需求,这是我一个做Java的朋友丢给我帮他实现行转列。
原始数据
转成这样的数据格式
思路:先把时间区间字段转成行,第二步把站点信息转成列。
select * from t_station_info;
一、把时间节点转换成行
with v_pivot as(select *
from t_station_info
unpivot(qty for timepoint in(TIME06_1,TIME06_2,TIME07_1,TIME07_2,TIME08_1,TIME08_2,TIME09_1,TIME09_2,
TIME10_1,TIME10_2,TIME11_1,TIME11_2,TIME12_1,TIME12_2,TIME13_1,TIME13_2,
TIME14_1,TIME14_2,TIME15_1,TIME15_2,TIME16_1,TIME16_2,TIME17_1,TIME17_2,
TIME18_1,TIME18_2,TIME19_1,TIME19_2,TIME20_1,TIME20_2,TIME21_1,TIME21_2,
TIME22_1,TIME22_2)));
二、把站点名称转成列标题
,v_pivot as(
select *
from v_unpivot
pivot(sum(qty)
for station in('下麦西站' as 下麦西站, --此处支持别名
'老湾塘站' as 老湾塘站,
'阅山湖公园站' as 阅山湖公园站,
'林城西路站' as 林城西路站,
'观山湖公园站' as 观山湖公园站,
'国际生态会议中心站' as 国际生态会议中心站,
'阳关站' as 阳关站,
'新寨站' as 新寨站,
'白鹭湖站' as 白鹭湖站,
'贵阳北站' as 贵阳北站))
三、把TIME编号变成具体可读的时间段
做一张code和具体时间段名称对应的表并且设置orderID排序
select * from t_conf_station
关联配置表并按设定好的orderID排序
select b.name, a.*
from v_pivot ajoin t_conf_station b on a.timepoint = b.code
order by b.orderid;
--最终完整代码
with v_unpivot as(
select *
from t_station_info
unpivot(qty for timepoint in(TIME06_1,TIME06_2,TIME07_1,TIME07_2,TIME08_1,TIME08_2,TIME09_1,TIME09_2,
TIME10_1,TIME10_2,TIME11_1,TIME11_2,TIME12_1,TIME12_2,TIME13_1,TIME13_2,
TIME14_1,TIME14_2,TIME15_1,TIME15_2,TIME16_1,TIME16_2,TIME17_1,TIME17_2,
TIME18_1,TIME18_2,TIME19_1,TIME19_2,TIME20_1,TIME20_2,TIME21_1,TIME21_2,
TIME22_1,TIME22_2))
)
,v_pivot as(
select *
from v_unpivot
pivot(sum(qty)
for station in('下麦西站' as 下麦西站,
'老湾塘站' as 老湾塘站,
'阅山湖公园站' as 阅山湖公园站,
'林城西路站' as 林城西路站,
'观山湖公园站' as 观山湖公园站,
'国际生态会议中心站' as 国际生态会议中心站,
'阳关站' as 阳关站,
'新寨站' as 新寨站,
'白鹭湖站' as 白鹭湖站,
'贵阳北站' as 贵阳北站))
)
select b.name, a.*
from v_pivot a
join t_conf_station b on a.timepoint = b.code
order by b.orderid