實現行列間轉換需求

在數據庫報表查詢時事實表中的數據很多情況下沒有直接反映最終報表需求的格式,其中很典型的就是要把多行的數據轉換成列的形式顯示,舉例如下:

事實表T_Score(學生成績表):

CREATE TABLE "DB2ADMIN"."T_SCORE"  (
    "NAME" VARCHAR(20) ,
    "SUBJECT" VARCHAR(20) ,
    "SCORE" INTEGER ) ;

 

示例數據:


 

Mary  Chinese    90
Mary  English     84
Mary  Maths      79
Tom   Chinese    86
Tom   English     93
Tom   Maths      89


 

 

但是報表需求:

NAME  Chinese      English      Maths


Mary   90             84            79
Tom    86             93            89


SQL實現:

select  name,
 sum(decode(subject,'Chinese',score)) as Chinese,
 sum(decode(subject,'English',score)) as English,
 sum(decode(subject,'Maths',score)) as Maths
from t_score group by name;

 

另外還有一種需求是希望把多行的數據合併到一列中,可以利用oracle的樹結構查詢獲得(connect by 語句):

select sys_connect_by_path(r_name,'|'),level LV from
(select r_name,row_number() over (order by id_stock desc) rn
from t_stocks_fact)  where level>3 connect by rn=prior rn+1;

 

至於列轉爲行則可以用union all來實現,以T_Score_Row爲例,

select name, 'Chinese' as subject, chinese from T_Score_Row

union all

select name, 'English' as subject, english from T_Score_Row

union all

select name, 'Maths' as subject, maths from T_Score_Row

以下SQL是上面行轉列過程的逆操作而已。

select * from (
select name, 'Chinese' as subject, chinese from (
select  name,
 sum(decode(subject,'Chinese',score)) as Chinese,
 sum(decode(subject,'English',score)) as English,
 sum(decode(subject,'Maths',score)) as Maths
from t_score group by name)
union all
select name, 'English' as subject, english from (
select  name,
 sum(decode(subject,'Chinese',score)) as Chinese,
 sum(decode(subject,'English',score)) as English,
 sum(decode(subject,'Maths',score)) as Maths
from t_score group by name
)
union all
select name, 'Maths' as subject, maths from (
select  name,
 sum(decode(subject,'Chinese',score)) as Chinese,
 sum(decode(subject,'English',score)) as English,
 sum(decode(subject,'Maths',score)) as Maths
from t_score group by name
)
) order by name

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章