Oracle行轉列的一次經歷
阿新 • • 發佈:2019-02-03
需求如下,由於系統專案改造,之前黨員各個月份的成績如下表所示:
存取資料如下:
新專案表結構作了調整,每個黨員每一年一條記錄,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;