1. 程式人生 > >[面試][oracle] 資料庫 行轉列 列轉行詳解

[面試][oracle] 資料庫 行轉列 列轉行詳解

[一]、行轉列

1.1、初始測試資料

表結構:TEST_TB_GRADE

create table TEST_TB_GRADE   
  1. (   
  2.   ID        NUMBER(10) notnull,   
  3.   USER_NAME VARCHAR2(20 CHAR),   
  4.   COURSE    VARCHAR2(20 CHAR),   
  5.   SCORE     FLOAT
  6. )  
  1. createtable TEST_TB_GRADE  
  2. (  
  3.   ID        NUMBER(10) notnull,  
  4.   USER_NAME VARCHAR2(20 CHAR
    ),  
  5.   COURSE    VARCHAR2(20 CHAR),  
  6.   SCORE     FLOAT
  7. )  

 初始資料如下圖:


                        

1.2、 如果需要實現如下的查詢效果圖:


                     

這就是最常見的行轉列,主要原理是利用decode函式、聚集函式(sum),結合group by分組實現的,具體的sql如下:

select t.user_name,   
  1. sum(decode(t.course, '語文', score,null)) as CHINESE,   
  2. sum(decode(t.course, 
    '數學', score,null)) as MATH,   
  3. sum(decode(t.course, '英語', score,null)) as ENGLISH   
  4. from test_tb_grade t   
  5. groupby t.user_name   
  6. orderby t.user_name  
  1. select t.user_name,  
  2.   sum(decode(t.course, '語文', score,null)) as CHINESE,  
  3.   sum(decode(t.course, '數學', score,null)) as MATH,  
  4.   sum(decode(t.course, 
    '英語', score,null)) as ENGLISH  
  5. from test_tb_grade t  
  6. groupby t.user_name  
  7. orderby t.user_name  

1.3、延伸

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


                 

具體的實現sql如下:

select t2.SCORE_GP,   
  1. sum(decode(t2.course, '語文', COUNTNUM,null)) as CHINESE,   
  2. sum(decode(t2.course, '數學', COUNTNUM,null)) as MATH,   
  3. sum(decode(t2.course, '英語', COUNTNUM,null)) as ENGLISH   
  4. from (   
  5. select t.course,   
  6. casewhen t.score  <60 then'00-60'
  7. when t.score >=60 and t.score <80  then'60-80'
  8. when t.score >=80 then'80-100'endas SCORE_GP,   
  9. count(t.score) as COUNTNUM   
  10. FROM test_tb_grade t   
  11. groupby t.course,    
  12. casewhen t.score  <60  then'00-60'
  13. when t.score >=60 and t.score <80  then'60-80'
  14. when t.score >=80 then'80-100'end
  15. orderby t.course ) t2   
  16. groupby t2.SCORE_GP   
  17. orderby t2.SCORE_GP  
  1. select t2.SCORE_GP,  
  2.   sum(decode(t2.course, '語文', COUNTNUM,null)) as CHINESE,  
  3.   sum(decode(t2.course, '數學', COUNTNUM,null)) as MATH,  
  4.   sum(decode(t2.course, '英語', COUNTNUM,null)) as ENGLISH  
  5. from (  
  6.   select t.course,  
  7.          casewhen t.score  <60 then'00-60'
  8.               when t.score >=60 and t.score <80  then'60-80'
  9.               when t.score >=80 then'80-100'endas SCORE_GP,  
  10.          count(t.score) as COUNTNUM  
  11.   FROM test_tb_grade t  
  12.   groupby t.course,   
  13.         casewhen t.score  <60  then'00-60'
  14.               when t.score >=60 and t.score <80  then'60-80'
  15.               when t.score >=80 then'80-100'end
  16.   orderby t.course ) t2  
  17. groupby t2.SCORE_GP  
  18. orderby t2.SCORE_GP  

[二]、列轉行

1.1、初始測試資料

        表結構:TEST_TB_GRADE2

create table TEST_TB_GRADE2   
  1. (   
  2.   ID         NUMBER(10) notnull,   
  3.   USER_NAME  VARCHAR2(20 CHAR),   
  4.   CN_SCORE   FLOAT,   
  5.   MATH_SCORE FLOAT,   
  6.   EN_SCORE   FLOAT
  7. )  
  1. createtable TEST_TB_GRADE2  
  2. (  
  3.   ID         NUMBER(10) notnull,  
  4.   USER_NAME  VARCHAR2(20 CHAR),  
  5.   CN_SCORE   FLOAT,  
  6.   MATH_SCORE FLOAT,  
  7.   EN_SCORE   FLOAT
  8. )  

        初始資料如下圖:


        

1.2、 如果需要實現如下的查詢效果圖:


                       

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

select user_name, '語文' COURSE , CN_SCORE as SCORE from test_tb_grade2    
  1. unionselect user_name, '數學' COURSE, MATH_SCORE as SCORE from test_tb_grade2    
  2. unionselect user_name, '英語' COURSE, EN_SCORE as SCORE from test_tb_grade2    
  3. orderby user_name,COURSE   
  1. select user_name, '語文' COURSE , CN_SCORE as SCORE from test_tb_grade2   
  2. unionselect user_name, '數學' COURSE, MATH_SCORE as SCORE from test_tb_grade2   
  3. unionselect user_name, '英語' COURSE, EN_SCORE as SCORE from test_tb_grade2   
  4. orderby user_name,COURSE   

 也可以利用【 insert all into ... select 】來實現,首先需要先建一個表TEST_TB_GRADE3:

create table TEST_TB_GRADE3     
  1.     (    
  2.       USER_NAME VARCHAR2(20 CHAR),     
  3.       COURSE    VARCHAR2(20 CHAR),     
  4.       SCORE     FLOAT
  5.     )    
  1. createtable TEST_TB_GRADE3    
  2.     (   
  3.       USER_NAME VARCHAR2(20 CHAR),    
  4.       COURSE    VARCHAR2(20 CHAR),    
  5.       SCORE     FLOAT
  6.     )    

相關推薦

[面試][oracle] 資料庫 轉行

[一]、行轉列 1.1、初始測試資料 表結構:TEST_TB_GRADE create table TEST_TB_GRADE    (      ID        NUMBER(10) notnull,      USER_NAME VARCHAR2

oracle,一

select t.rank, t.Name from t_menu_item t;     10 CLARK     10 KING     10 MILLER     20 ADAMS     20 FORD     20 JONES     20 SCOTT     2

Oracle資料庫——union,union all 操作符

SQL UNION 操作符 UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。 請注意,UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的資料型別。同時,每條 SELECT 語句中的列的順序必須相同。 SQL UNION 語法 SELECT

Oracle資料庫悲觀鎖與樂觀鎖

Oracle資料庫悲觀鎖與樂觀鎖是本文我們主要要介紹的內容。有時候為了得到最大的效能,一般資料庫都有併發機制,不過帶來的問題就是資料訪問的衝突。為了解決這個問題,大多數資料庫用的方法就是資料的鎖定。 資料的鎖定分為兩種方法,第一種叫做悲觀鎖,第二種叫做樂觀鎖。什麼叫悲觀鎖呢,悲觀鎖顧名思義,就是對資料的衝突

資料庫 轉行

目錄結構如下: 行轉列 列轉行 [一]、行轉列 1.1、初始測試資料 表結構:TEST_TB_GRADE createtable TEST_TB_GRADE    (     ID        NUMBER(10) notnull,     USER_NAME

資料庫轉行小例子

有時候,我們想從另一個角度看一張表。這時候就會涉及行列的轉換。假如有一張成績表 mysql> select * from scores; +------+----------+-------+ | name | kemu     | score | +------+-

Oracle資料庫顯示轉換成顯示--pivot的應用

Create table tmp(types varchar(22) primary key,num int,maps int); insert into tmp (types, num, maps)values ('計劃收儲', 635, 50252909); insert into tm

Oracle pivot

行轉列語法為pivot(聚合函式 for 列名 in(型別)): pivot ( sum ( planqty ) for plantype in ( 'in', 'out' ) ) 1.建立測試表格 CREATE TABLE XXXMGR.FAB_BSFACTORYDAI

資料庫簡單例子

DECLARE @StuList TABLE (  Stu VARCHAR(20),  Course NVARCHAR(20),  Score DECIMAL ) INSERT INTO @StuList         ( Stu, Course, Score ) VAL

資料庫

有些時候還是要用到行轉列,比如下面的資料:一般的表結構大多會這麼設計,通過關聯查詢就可以得出上面的資料(客運量就隨便123了,非常時期以防恐怖分子)不用說,大家也明白要得到下面的資料:列數不多的話一般可以這樣,也是網上比較經典的寫法Select 時間, sum(case w

Oracle的函式wm_concat的db2實現

      oracle的行轉列的函式wm_concat的功能很強大,db2同樣有個名叫聚合函式listagg()可以實現此功能       select listagg(id,',') from student;     listagg函式的詳細介紹:

oracle 11g 的問題 decode實現與pivot實現

oracle 11g 行轉列的問題舉一個簡單的例子,假設有表名為demo其中只有兩列一列為型別names,一列為數量nums。表中資料如下:目標統計出表中apple及orange各自的總數,在一列中顯示出來。常規寫法:select names,sum(nums) from d

檢視ORACLE 資料庫的表和的相關資訊

本文全部轉載自:http://www.cnblogs.com/tearer/archive/2012/12/13/2815601.html 供自己收藏學習。 -------------------------------------------------------------------

hiveLATERAL VIEW explode

lateral view用於和split、explode等UDTF一起使用的,能將一行資料拆分成多行資料,在此基礎上可以對拆分的資料進行聚合,lateral view首先為原始表的每行呼叫UDTF,UDTF會把一行拆分成一行或者多行,lateral view在把結果組合,產生一個支援別名表的

單純的將資料怎麼實現(急急急)

已解決一個web登入系統的如何訪問資料庫 innobackupex備份mysql速度如何? 求助一個mysql儲存過程的問題51 已解決mysqlcluster關於管理節點的問題 匭鼐uth茸陀儼http://baoba

Oracle資料庫批量更新某資料

先講下我遇到的情況:  有一張表a,已經存在一個欄位該欄位是date型別,需求將該欄位改為varchar2()型別,我們都知道, Oracle在該欄位有值情況是不可以更新資料的,如果你不在乎該欄位在表

SQL多

表內容: 姓名 課程 分數 張三 語文 74張三 數學 83張三 物理 93張三 德語 null李四 語文 74李四 數學 84李四 物理 94李四 英語 80想變成(得到如下結果): 姓名 語文 數學 物理 英語 德語---- ---- ---- ----李四 74   

行列轉換之——多,多實踐版

多行 max 演示 spa info 思想 .com 要求 列轉行 行列轉換之——多行轉多列,多列轉多行實踐版 1、多列轉行(核心思想,利用row_number() over() 來構造列傳行之後的唯一列,來行轉列)   要求:     實操演示: select

數和數不確定

原始需求,有2表如下 SQL> select * from mas; TO TOOLNAME -- ---------- 01 包裹 02 信函 03 掛號信 04 中國速遞 05 EMS 06 DHL 6 rows selected. SQL> select * from putdt; SEN

004_008 Python 化成轉化成行

程式碼如下: #encoding=utf-8 print '中國' #二維陣列變換 行轉化成列,列轉化成行 lista=[[1,2,3],[4,5,6],[7,8,9],[10,11,12]] #使用列表推導 listb=[[r[col] for r in lista