Oracle行转列的一次经历

需求如下,由于系统项目改造,之前党员各个月份的成绩如下表所示:

这里写图片描述
存取数据如下:
这里写图片描述

新项目表结构作了调整,每个党员每一年一条记录,12个月份的数据变成了列字段,主键变成由年份和党员id构成,表结构如下:

这里写图片描述

月统计得分和季统计得分的数据存储是有格式要求的,如下:
这里写图片描述

由于需要数据迁移,我把之前的表放到新版数据库中,通过编写一共存储过程实现考核数据转换。(这次经历主要是目前统计考核规则有问题,数据需要重新计算)

由于每一个月份的数据组装格式如下:

{"zdl":"4.20","xxjy":"3.50","zzsh":"31.00","yxl":"3.30","total":"42.00"}

所以:很自然考虑如下SQL

select member_id,year,quart,
              '{"zdl":"'||party_zdl||'","xxjy":"'||party_xxjy||'","zzsh":"'||party_zch||'","yxl":"'||party_yxl||'","total":"'||party_total||'"}' as mm
              from t_statistic_partytemp_hbk order by member_id 

查询的数据如下:

这里写图片描述
这个只是数据json格式的组织,每个党员id有6个月份的数据(即每个党员6条记录,当前月份是7月份,项目运行到现在只有前6月份的数据,正常的话一年有12个月的)

如何通过行记录转换成列记录呢?
网上也学习了好几篇博客,但是需求都不一样,最终还是自己搞了一个,成就感满满。

我通过月份字段quart,使用case when else end语句生成m1,m2,m3,m4,m5,m6字段
SQL如下,在原来的SQL外层进行包装:

select b.member_id,b.year,
            case b.quart when '01' then b.mm else null end as m1,
            case b.quart when '02' then b.mm else null end as m2,
            case b.quart when '03' then b.mm else null end as m3,
            case b.quart when '04' then b.mm else null end as m4,
            case b.quart when '05' then b.mm else null end as m5,
            case b.quart when '06' then b.mm else null end as m6
            from 
            (
              select member_id,year,quart,
              '{"zdl":"'||party_zdl||'","xxjy":"'||party_xxjy||'","zzsh":"'||party_zch||'","yxl":"'||party_yxl||'","total":"'||party_total||'"}' as mm
              from t_statistic_partytemp_hbk order by member_id 
            ) b

这里写图片描述

虽然说离真正的数据结构不远,我们想办法对数据进行合并,即由6条数据变成一条,并且填充m1到m6字段的值。

也是通过网上的学习,学习到 wmsys.wm_concat函数的
再一次包装:

select c.member_id,
    c.year,
        wmsys.wm_concat(c.m1) as m1,
        wmsys.wm_concat(c.m2) as m2,
        wmsys.wm_concat(c.m3) as m3,
        wmsys.wm_concat(c.m4) as m4,
        wmsys.wm_concat(c.m5) as m5,
        wmsys.wm_concat(c.m6) as m6 from 
        (
            select b.member_id,b.year,
            case b.quart when '01' then b.mm else null end as m1,
            case b.quart when '02' then b.mm else null end as m2,
            case b.quart when '03' then b.mm else null end as m3,
            case b.quart when '04' then b.mm else null end as m4,
            case b.quart when '05' then b.mm else null end as m5,
            case b.quart when '06' then b.mm else null end as m6
            from 
            (
              select member_id,year,quart,
              '{"zdl":"'||party_zdl||'","xxjy":"'||party_xxjy||'","zzsh":"'||party_zch||'","yxl":"'||party_yxl||'","total":"'||party_total||'"}' as mm
              from t_statistic_partytemp_hbk order by member_id 
            ) b
       ) c group by c.member_id,c.year

这里写图片描述
终于生成了我们想要的数据格式:合并技巧,因为每一个月只有一个月列字段有值,所以使用wmsys.wm_concat()函数进行合并的时候,只留下了当前列。

业务需求的问题,党员编码是新规则生成。
需要通过左连接进行关联,这么一大段SQL,于是我封装成一个视图。

CREATE OR REPLACE VIEW DATA_ROWS AS select c.member_id,
    c.year,
        wmsys.wm_concat(c.m1) as m1,
        wmsys.wm_concat(c.m2) as m2,
        wmsys.wm_concat(c.m3) as m3,
        wmsys.wm_concat(c.m4) as m4,
        wmsys.wm_concat(c.m5) as m5,
        wmsys.wm_concat(c.m6) as m6 from 
        (
            select b.member_id,b.year,
            case b.quart when '01' then b.mm else null end as m1,
            case b.quart when '02' then b.mm else null end as m2,
            case b.quart when '03' then b.mm else null end as m3,
            case b.quart when '04' then b.mm else null end as m4,
            case b.quart when '05' then b.mm else null end as m5,
            case b.quart when '06' then b.mm else null end as m6
            from 
            (
              select member_id,year,quart,
              '{"zdl":"'||party_zdl||'","xxjy":"'||party_xxjy||'","zzsh":"'||party_zch||'","yxl":"'||party_yxl||'","total":"'||party_total||'"}' as mm
              from t_statistic_partytemp_hbk order by member_id 
            ) b
       ) c group by c.member_id,c.year;

存储过程如下:

/**
  =================章贡区之前2018年01-06月份的数据进行迁移=======================
  =================算法简单介绍=====================
  1、DATA_ROWS为创建的视图,通过编写SQL语句,转换成相关字段数据格式。
  2、使用insert into  select语句进行插入,关联条件为视图的member_id=temp_memberid_pm.member_id
  3、id主键有年份和党员编码构成。
  4、提交事务

**/
CREATE OR REPLACE PROCEDURE PARTY_STATISTIC_MOVE_HBK AS 

begin
  insert into t_assessment_pm(id,pm_code,year,m1,m2,m3,m4,m5,m6)
  select d.year||pm.pm_code as id,pm.pm_code,d.year,d.m1,d.m2,d.m3,d.m4,d.m5,d.m6 
  from data_rows d , temp_memberid_pm pm where d.member_id=pm.member_id ;
  commit;

end party_statistic_move_hbk;

专业墙纸贴纸厨房用具装饰出售,本人网店经营,访问即是爱

博客对你有用记得访问下哦,增加下访问量,如有需要可以下单购买哦^_^。店铺地址https://item.taobao.com/item.htm?id=570637716145

猜你喜欢

转载自blog.csdn.net/huangbaokang/article/details/81080409
今日推荐