天天看點

資料庫 行轉列 列轉行詳解

目錄結構如下:

行轉列

列轉行

[一]、行轉列

1.1、初始測試資料

表結構:TEST_TB_GRADE

create table TEST_TB_GRADE   

(

  ID        NUMBER(10) not null,

  USER_NAME VARCHAR2(20 CHAR),

  COURSE    VARCHAR2(20 CHAR),

  SCORE     FLOAT  

)  

<b>[sql]</b> 

create table TEST_TB_GRADE  

(  

  ID        NUMBER(10) not null,  

  USER_NAME VARCHAR2(20 CHAR),  

  COURSE    VARCHAR2(20 CHAR),  

 初始資料如下圖:

資料庫 行轉列 列轉行詳解

1.2、

如果需要實作如下的查詢效果圖:

資料庫 行轉列 列轉行詳解

這就是最常見的行轉列,主要原理是利用decode函數、聚集函數(sum),結合group

by分組實作的,具體的sql如下:

select t.user_name,   

  sum(decode(t.course, ‘國文‘, score,null)) as CHINESE,

  sum(decode(t.course, ‘數學‘, score,null)) as MATH,

  sum(decode(t.course, ‘英語‘, score,null)) as ENGLISH

from test_tb_grade t

group by t.user_name

order by t.user_name  

select t.user_name,  

  sum(decode(t.course, ‘國文‘, score,null)) as CHINESE,  

  sum(decode(t.course, ‘數學‘, score,null)) as MATH,  

  sum(decode(t.course, ‘英語‘, score,null)) as ENGLISH  

from test_tb_grade t  

group by t.user_name  

1.3、延伸

如果要實作對各門功課的不同分數段進行統計,效果圖如下:

資料庫 行轉列 列轉行詳解

具體的實作sql如下:

select t2.SCORE_GP,   

  sum(decode(t2.course, ‘國文‘, COUNTNUM,null)) as CHINESE,

  sum(decode(t2.course, ‘數學‘, COUNTNUM,null)) as MATH,

  sum(decode(t2.course, ‘英語‘, COUNTNUM,null)) as ENGLISH

from (

  select t.course,

         case when t.score  &lt;60 then ‘00-60‘  

              when t.score &gt;=60 and t.score &lt;80  then ‘60-80‘  

              when t.score &gt;=80 then ‘80-100‘ end as SCORE_GP,

         count(t.score) as COUNTNUM

  FROM test_tb_grade t

  group by t.course, 

        case when t.score  &lt;60  then ‘00-60‘  

              when t.score &gt;=80 then ‘80-100‘ end  

  order by t.course ) t2

group by t2.SCORE_GP

order by t2.SCORE_GP  

select t2.SCORE_GP,  

  sum(decode(t2.course, ‘國文‘, COUNTNUM,null)) as CHINESE,  

  sum(decode(t2.course, ‘數學‘, COUNTNUM,null)) as MATH,  

  sum(decode(t2.course, ‘英語‘, COUNTNUM,null)) as ENGLISH  

from (  

  select t.course,  

              when t.score &gt;=80 then ‘80-100‘ end as SCORE_GP,  

         count(t.score) as COUNTNUM  

  FROM test_tb_grade t  

  group by t.course,   

  order by t.course ) t2  

group by t2.SCORE_GP  

[二]、列轉行

表結構:TEST_TB_GRADE2

create table TEST_TB_GRADE2   

  ID         NUMBER(10) not null,

  USER_NAME  VARCHAR2(20 CHAR),

  CN_SCORE   FLOAT,

  MATH_SCORE FLOAT,

  EN_SCORE   FLOAT  

create table TEST_TB_GRADE2  

  ID         NUMBER(10) not null,  

  USER_NAME  VARCHAR2(20 CHAR),  

  CN_SCORE   FLOAT,  

  MATH_SCORE FLOAT,  

初始資料如下圖:

資料庫 行轉列 列轉行詳解
資料庫 行轉列 列轉行詳解

這就是最常見的列轉行,主要原理是利用SQL裡面的union,具體的sql語句如下:

select user_name, ‘國文‘ COURSE , CN_SCORE as SCORE from test_tb_grade2    

union select user_name, ‘數學‘ COURSE, MATH_SCORE as SCORE from test_tb_grade2 

union select user_name, ‘英語‘ COURSE, EN_SCORE as SCORE from test_tb_grade2 

order by user_name,COURSE   

select user_name, ‘國文‘ COURSE , CN_SCORE as SCORE from test_tb_grade2   

union select user_name, ‘數學‘ COURSE, MATH_SCORE as SCORE from test_tb_grade2   

union select user_name, ‘英語‘ COURSE, EN_SCORE as SCORE from test_tb_grade2   

 也可以利用【 insert all into ...

select 】來實作,首先需要先建一個表TEST_TB_GRADE3:

create table TEST_TB_GRADE3     

    ( 

      USER_NAME VARCHAR2(20 CHAR),  

      COURSE    VARCHAR2(20 CHAR),  

      SCORE     FLOAT  

    )    

create table TEST_TB_GRADE3    

    (   

      USER_NAME VARCHAR2(20 CHAR),    

      COURSE    VARCHAR2(20 CHAR),    

      SCORE     FLOAT    

 再執行下面的sql:

insert all  

into test_tb_grade3(USER_NAME,COURSE,SCORE) values(user_name, ‘國文‘, CN_SCORE)

into test_tb_grade3(USER_NAME,COURSE,SCORE) values(user_name, ‘數學‘, MATH_SCORE)

into test_tb_grade3(USER_NAME,COURSE,SCORE) values(user_name, ‘英語‘, EN_SCORE)

select user_name, CN_SCORE, MATH_SCORE, EN_SCORE from test_tb_grade2;

commit;  

into test_tb_grade3(USER_NAME,COURSE,SCORE) values(user_name, ‘國文‘, CN_SCORE)  

into test_tb_grade3(USER_NAME,COURSE,SCORE) values(user_name, ‘數學‘, MATH_SCORE)  

into test_tb_grade3(USER_NAME,COURSE,SCORE) values(user_name, ‘英語‘, EN_SCORE)  

select user_name, CN_SCORE, MATH_SCORE, EN_SCORE from test_tb_grade2;  

 别忘記commit操作,然後再查詢TEST_TB_GRADE3,發現表中的資料就是列轉成行了。

本文連接配接:http://sjsky.iteye.com/blog/1152167

來源: &lt;&gt;