sql行轉列和列轉行
阿新 • • 發佈:2019-01-09
最近建立資料立方體需要將表的資料結構進行轉換,進行列轉行,覺得用途還很大,所以就整理一下,當做自己的筆記拉。
1、列轉行(主要)
表weatherdata結構:
資料示例如下:create table WEATHERDATA ( 路徑 VARCHAR2(100), 日期 VARCHAR2(50), 時間 VARCHAR2(30), 溫度 VARCHAR2(50), P0 VARCHAR2(50), P VARCHAR2(50), PA VARCHAR2(50), 溼度 VARCHAR2(10), 風向 VARCHAR2(100), 風速 VARCHAR2(50), FF10 VARCHAR2(100), FF3 VARCHAR2(100), 總雲量 VARCHAR2(100), WW VARCHAR2(200), W1 VARCHAR2(100), W2 VARCHAR2(100), TN VARCHAR2(100), TX VARCHAR2(100), CL VARCHAR2(200), NH VARCHAR2(100), H VARCHAR2(100), CM VARCHAR2(200), CH VARCHAR2(200), VV VARCHAR2(100), TD VARCHAR2(100), RRR VARCHAR2(100), TR VARCHAR2(100), E VARCHAR2(100), TG VARCHAR2(100), E1 VARCHAR2(100), SSS VARCHAR2(100) )
需要裝換的效果:
轉換成五列,原來表中溫度,P0,P,PA,溼度,風向,風速等對應INDI的屬性id值,VALUE為每個屬性對應值。
sql程式碼:
按照自己的需求可以參考。select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '24' indi,溫度 as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '25' indi,P0 as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '26' indi,P as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '27' indi,PA as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '28' indi,溼度 as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '29' indi,風向 as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '30' indi,風速 as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '31' indi,FF10 as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '32' indi,FF3 as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '33' indi,總雲量 as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '34' indi,WW as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '35' indi,W1 as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '36' indi,W2 as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '37' indi,TN as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '38' indi,TX as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '39' indi,CL as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '40' indi,NH as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '41' indi,H as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '42' indi,CM as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '43' indi,CH as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '44' indi,VV as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '45' indi,TD as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '46' indi,RRR as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '47' indi,TR as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '48' indi,E as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '49' indi,TG as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '50' indi,E1 as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 union select key2 as 路徑,to_date(replace(replace(replace(substr(日期,0,12),'年 ','/'),'月 ','/'),'日',''),'yy/mm/dd') as 日期,key as 時間, '51' indi,SSS as value from weatherdata a,T72090608 b,area_id c where a.時間 = b.name and a.路徑 = c.路徑 order by 路徑,日期,時間,indi
2、行轉列
行轉列效果相反,主要原理是利用decode函式(將查詢結果翻譯成其他值)、聚集函式(sum,max,min),結合group by 分組實現。這邊簡單說下:
sql程式碼如下:
select t.area,t.date1,t.time, sum(decode(t.indi, '24', value,null)) as 溫度, sum(decode(t.indi, '25', value,null)) as P0, sum(decode(t.indi, '26', value,null)) as P, sum(decode(t.indi, '27', value,null)) as PA, max(decode(t.indi, '28', value,null)) as 溼度, max(decode(t.indi, '29', value,null)) as 風向, sum(decode(t.indi, '30', value,null)) as 風速, sum(decode(t.indi, '31', value,null)) as FF10, sum(decode(t.indi, '32', value,null)) as FF3, sum(decode(t.indi, '33', value,null)) as 總雲量, sum(decode(t.indi, '34', value,null)) as WW, sum(decode(t.indi, '35', value,null)) as W1, sum(decode(t.indi, '36', value,null)) as W2, sum(decode(t.indi, '37', value,null)) as TN, sum(decode(t.indi, '38', value,null)) as TX, sum(decode(t.indi, '39', value,null)) as CL, sum(decode(t.indi, '40', value,null)) as NH, sum(decode(t.indi, '41', value,null)) as H, sum(decode(t.indi, '42', value,null)) as CM, sum(decode(t.indi, '43', value,null)) as CH, sum(decode(t.indi, '44', value,null)) as VV, sum(decode(t.indi, '45', value,null)) as TD, sum(decode(t.indi, '46', value,null)) as RRR, sum(decode(t.indi, '47', value,null)) as TR, sum(decode(t.indi, '48', value,null)) as E, sum(decode(t.indi, '49', value,null)) as TG, sum(decode(t.indi, '50', value,null)) as E1, sum(decode(t.indi, '51', value,null)) as SSS from WEATHER1 t group by t.area,t.date1,t.time
decode函式代表含義:
if (t.indi==24)
then
return(value)//溫度對應值
else
return(null)
注意:行轉列時,聚集函式的使用,一般非數字型別的欄位不能用sum,可用max或min代替。