成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何用Pivot實現行列轉換

數據庫 Oracle
在Oracle中,如果要實現行列轉換,較為常見的是用DECODE和CASE語句。對于簡單的行列轉行,DECODE和CASE語句尚能應付。在邏輯比較復雜,分組聚合較多的場景中,DECODE和CASE語句則力有不逮。而pivot則可完美解決這一切。

   首先,我們來看看Oracle對于其的解釋:

 

  可見,pivot是數據倉庫中的關鍵技術,它利用交叉查詢(crosstabulation query)將行轉換為列。

  基本語法如下:

 

  1. SELECT .... 
  2. FROM <table-expr> 
  3.    PIVOT 
  4.      ( 
  5.       aggregate-function(<column>) 
  6.       FOR <pivot-columnIN (<value1>, <value2>,..., <valuen>) 
  7.         ) AS <alias> 
  8. WHERE ..... 

 

  下面我們來通過具體的案例對其進行闡述。

  首先,構造案例所需的數據,

  1> 創建視圖,以EMP表的數據作為源數據。

 

  1. CREATE VIEW emp_view AS 
  2. SELECT 
  3.  deptno,job,to_char(hiredate,'yyyy') hiredate, 
  4.  count(*) cnt,sum(sal) sum_sal 
  5. FROM emp 
  6. GROUP BY deptno,job,to_char(hiredate,'yyyy'); 

 

  其中,deptno為部門號,job為工作的類型(即工種),hiredate為雇傭的日期,cnt為特定部門,特定工種在特定年份雇傭的員工的總數,sum_sal為特定部門,特定工種,特定年份雇傭的員工的工資的總和。

  2> 視圖的數據如下:

 

  1. SQL> select * from emp_view; 
  2.  
  3.     DEPTNO JOB       HIRE        CNT    SUM_SAL 
  4. ---------- --------- ---- ---------- ---------- 
  5. CLERK     1980          1        800 
  6. ANALYST   1981          1       3000 
  7. ANALYST   1987          1       3000 
  8. CLERK     1981          1        950 
  9. MANAGER   1981          1       2850 
  10. MANAGER   1981          1       2450 
  11. SALESMAN  1981          4       5600 
  12. MANAGER   1981          1       2975 
  13. PRESIDENT 1981          1       5000 
  14. CLERK     1982          1       1300 
  15. CLERK     1987          1       1100 
  16. rows selected. 

 

  應用場景一:

  基本的Pivot轉換

  例1:

 

  1. SELECT * FROM 
  2. SELECT deptno,hiredate,cnt 
  3.   FROM emp_view 
  4.  ) PIVOT (SUM(cnt) 
  5.    FOR hiredate IN ('1980' AS "1980",'1981' AS "1981"
  6.                     '1982' AS "1982",'1987' AS "1987")) 
  7. ORDER BY deptno; 
  8.  
  9.     DEPTNO       1980       1981       1982       1987 
  10. ---------- ---------- ---------- ---------- ---------- 
  11.                     2          1 
  12.          1          2                     2 
  13.                     6 
  14. rows selected. 

 

  例2:

 

  1. SELECT * FROM 
  2. SELECT deptno,job,cnt 
  3.   FROM emp_view 
  4.  ) PIVOT (SUM(cnt) 
  5.    FOR job IN ('CLERK','ANALYST','MANAGER','SALESMAN','PRESIDENT')) 
  6. ORDER BY deptno; 
  7.  
  8.     DEPTNO    'CLERK'  'ANALYST'  'MANAGER' 'SALESMAN' 'PRESIDENT' 
  9. ---------- ---------- ---------- ---------- ---------- ----------- 
  10.          1                     1                      1 
  11.          2          2          1 
  12.          1                     1          4 
  13. rows selected. 

 

  兩例以不同的列進行統計,前者是hiredate,后者是job。

  除此之外,前者用了別名,后面沒有用別名,兩者的顯示效果也是不一樣的。

  應用場景二:

  對多列進行Pivot轉換

 

  1. SELECT * FROM 
  2. SELECT deptno,job,hiredate,cnt 
  3.   FROM emp_view 
  4.  ) PIVOT (SUM(cnt) 
  5.             FOR (job,hiredate) IN 
  6.               (('CLERK','1980'AS clerk_1980, 
  7.                ('CLERK','1981'AS clerk_1981, 
  8.                ('ANALYST','1987'AS analyst_1987, 
  9.                ('MANAGER','1981'AS manager_1981 
  10.               ) 
  11.            ) 
  12. ORDER by deptno; 
  13.  
  14.     DEPTNO CLERK_1980 CLERK_1981 ANALYST_1987 MANAGER_1981 
  15. ---------- ---------- ---------- ------------ ------------ 
  16.                                               1 
  17.          1                       1            1 
  18.                     1                         1 
  19. rows selected. 

 

  限于篇幅,FOR (job,hiredate) IN語句中沒有列出更多組合,只列出了四組,當然,我們可以根據實際場景需要羅列更多的組合。

  從本例中可以看出,對兩個列進行Pivot轉換可從三個維度呈現統計結果。

  應用場景三:

  用Pivot實現多個聚合

 

  1. SELECT * FROM 
  2. SELECT deptno,hiredate,cnt,sum_sal 
  3.   FROM emp_view 
  4.  ) PIVOT ( SUM(cnt) AS cnt, 
  5.            SUM(sum_sal) AS sum_sal 
  6.            FOR hiredate IN ('1980','1981','1982','1987')) 
  7. ORDER BY deptno; 
  8.  
  9.     DEPTNO '1980'_CNT '1980'_SUM_SAL '1981'_CNT '1981'_SUM_SAL '1982'_CNT '1982'_SUM_SAL '1987'_CNT '1987'_SUM_SAL 
  10. ---------- ---------- -------------- ---------- -------------- ---------- -------------- ---------- -------------- 
  11.                                    2           7450          1           1300 
  12.          1            800          2           5975                                    2           4100 
  13.                                    6           9400 
  14. rows selected. 

 

  '1981'_CNT指的是1981年雇傭的員工的總數,'1981'_SUM_SAL指的是1981年雇傭員工所開出的工資。

  具體到本例中,即1981年10號部門招聘了2位員工,開出的工資合計為7450元,20號部門招聘了2位員工,開出的工資合計為5975元,30號部門招聘了6名員工,開出的工資合計為9400元,依次類推。

  既然有pivot將行轉換為列,同樣也有unpivot操作將聚合后的列轉換為行。

  UNPIVOT

  以上述應用場景三的結果作為源數據進行操作

 

  1. CREATE TABLE T1 AS 
  2. SELECT * FROM 
  3. SELECT deptno,hiredate,cnt,sum_sal 
  4.   FROM emp_view 
  5.  ) PIVOT ( SUM(cnt) AS cnt, 
  6.            SUM(sum_sal) AS sum_sal 
  7.            FOR hiredate IN ('1980' AS "1980",'1981' AS "1981"
  8.                             '1982' AS "1982",'1987' AS "1987")) 
  9. ORDER BY deptno 

 

  表T1的結果為:

 

  1. SQL> select * from t1; 
  2.  
  3.     DEPTNO   1980_CNT 1980_SUM_SAL   1981_CNT 1981_SUM_SAL   1982_CNT 1982_SUM_SAL   1987_CNT 1987_SUM_SAL 
  4. ---------- ---------- ------------ ---------- ------------ ---------- ------------ ---------- ------------ 
  5.                                  2         7450          1         1300 
  6.          1          800          2         5975                                  2         4100 
  7.                                  6         9400 
  8. rows selected. 

 

  首先進行一維unpivot

 

  1. SELECT deptno,DECODE(hiredate,'1980_CNT','1980','1981_CNT','1981','1982_CNT','1982','1987_CNT','1987'AS hiredate,cnt 
  2. FROM T1 
  3. UNPIVOT INCLUDE NULLS 
  4. ( cnt 
  5.   FOR hiredate IN ("1980_CNT","1981_CNT","1982_CNT","1987_CNT")); 
  6.  
  7.     DEPTNO HIRE        CNT 
  8. ---------- ---- ---------- 
  9. 1980 
  10. 1981          2 
  11. 1982          1 
  12. 1987 
  13. 1980          1 
  14. 1981          2 
  15. 1982 
  16. 1987          2 
  17. 1980 
  18. 1981          6 
  19. 1982 
  20. 1987 
  21. rows selected. 

 

  輸出的結果為不同部門在不同年份的雇傭人數,

  注意:上述SQL語句中UNPIVOT后加了INCLUDE NULLS,當然也可以指定為EXCLUDE NULLS,即排除cnt為空的值,如果不指定,則默認為EXCLUDE NULLS。

  UNPIVOT后不指定INCLUDE NULLS的輸入結果為:

 

  1. DEPTNO HIRE        CNT 
  2. ---------- ---- ---------- 
  3. 1981          2 
  4. 1982          1 
  5. 1980          1 
  6. 1981          2 
  7. 1987          2 
  8. 1981          6 
  9. rows selected. 

 

  下面,我們再進行二維unpivot

 

  1. SELECT deptno,hiredate,cnt,sum_sal 
  2. FROM T1 
  3. UNPIVOT 
  4. ( (cnt,sum_sal) 
  5.   FOR hiredate IN (("1980_CNT","1980_SUM_SAL"AS 1980, 
  6.                    ("1981_CNT","1981_SUM_SAL"AS 1981, 
  7.                    ("1982_CNT","1982_SUM_SAL"AS 1982, 
  8.                    ("1987_CNT","1987_SUM_SAL"AS 1987)); 
  9.  
  10.     DEPTNO   HIREDATE        CNT    SUM_SAL 
  11. ---------- ---------- ---------- ---------- 
  12.       1981          2       7450 
  13.       1982          1       1300 
  14.       1980          1        800 
  15.       1981          2       5975 
  16.       1987          2       4100 
  17.       1981          6       9400 
  18. rows selected. 

 

  輸入結果為T1表列轉行的結果。

  參考文檔:

  SQL for Analysis and Reporting

責任編輯:honglu 來源: 博客園
相關推薦

2011-07-15 09:04:42

PIVOTUNPIVOT

2011-03-15 14:26:23

iptablesNAT

2024-05-17 08:52:43

SQL實用技巧行列轉換

2011-03-15 09:10:47

iptablesNAT

2010-03-04 15:24:14

Python程序

2020-05-09 10:38:31

Python透視表數據

2018-03-15 14:07:17

潤乾Excel行列轉換

2016-09-26 15:14:28

Javascript前端vue

2010-05-24 10:23:34

實現MySQL

2017-10-11 16:19:36

jquery留言框設計

2017-10-27 22:03:35

javascrip

2018-03-30 10:26:24

行間距行高iOS

2021-03-02 10:57:39

二叉樹二叉堆節點

2010-05-25 13:47:53

MySQL 命令

2017-04-26 08:31:10

神經網絡自然語言PyTorch

2018-08-31 09:55:38

Ansible網絡自動化

2009-02-05 14:17:37

FTP服務器Java

2023-10-26 11:03:50

C語言宏定義

2015-07-06 13:36:14

Redis微博關注關系

2023-02-26 01:37:57

goORM代碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人二区| 欧美日韩视频在线 | 精品国产综合 | 一区二区影院 | 成人a视频在线观看 | 亚洲最大av网站 | 国产视频久 | 成人性生交大片免费看r链接 | 国产免费一区二区三区免费视频 | 国产二区三区 | 国产免费让你躁在线视频 | 欧美中文字幕在线观看 | 99福利视频 | 久久综合久久久 | 亚洲精品久久久一区二区三区 | 国产成人一区二区三区电影 | 久久国产精品精品国产色婷婷 | 国产高清精品一区二区三区 | 国产一区日韩在线 | 日韩欧美精品一区 | 国产精久久久久久 | 在线视频一区二区 | 天天爱爱网 | 久久成人精品一区二区三区 | 欧美精品v | 久久91精品久久久久久9鸭 | 中文字幕一级 | 欧美日韩中文在线 | 精品国产乱码久久久久久图片 | 中文字幕在线视频观看 | 男女性毛片 | 在线一区视频 | 91欧美精品成人综合在线观看 | 欧美日韩国产一区二区三区 | 国产精品精品 | 国产aⅴ爽av久久久久久久 | 午夜电影网 | 久久婷婷国产麻豆91 | 日韩手机在线视频 | 国产精品视频免费看 | 亚洲一区二区电影网 |