oracle行列轉換-列轉行

pwz1688發表於2014-01-03
在itpub論壇看到一則貼子,行列轉換總結,寫的很全面。現將我的測試結果覆上來,留著日後參考。
附上測試指令碼,有表及表中資料如下

點選(此處)摺疊或開啟

  1. SQL> create table t_col_row(
  2.   2 id int,
  3.   3 c1 varchar2(10),
  4.   4 c2 varchar2(10),
  5.   5 c3 varchar2(10));

  6. 表已建立。

  7. SQL> insert into t_col_row values(1,'v11','v21','v31');

  8. 已建立 1 行。

  9. SQL> insert into t_col_row values(2,'v12','v22',null);

  10. 已建立 1 行。

  11. SQL> insert into t_col_row values(3,'v13',null,'v33');

  12. 已建立 1 行。

  13. SQL> insert into t_col_row values(4,null,'v24','v34');

  14. 已建立 1 行。

  15. SQL> insert into t_col_row values(5,'v15',null,null);

  16. 已建立 1 行。

  17. SQL> insert into t_col_row values(6,null,null,'v35');

  18. 已建立 1 行。

  19. SQL> insert into t_col_row values(7,null,null,null);

  20. 已建立 1 行。

  21. SQL> commit;

  22. 提交完成。
查詢t_col_row表中資料如下:

SQL> select * from t_col_row;

        ID C1         C2         C3
---------- ---------- ---------- ----------
         1 v11        v21        v31
         2 v12        v22
         3 v13                   v33
         4            v24        v34
         5 v15
         6                       v35
         7

已選擇7行。


現要將此表資料做列轉行,共有三種方法,如下:
1)UNION ALL
適用範圍:8i,9i,10g及以後版本

點選(此處)摺疊或開啟

  1. SQL> select id,'c1' cn,c1 cv from t_col_row
  2.   2 union all
  3.   3 select id,'c2' cn,c2 cv from t_col_row
  4.   4 union all
  5.   5 select id,'c3' cn,c3 cv from t_col_row;

  6.         ID CN CV
  7. ---------- -- ----------

  8.          1 c1 v11
  9.          2 c1 v12
  10.          3 c1 v13
  11.          4 c1
  12.          5 c1 v15
  13.          6 c1
  14.          7 c1
  15.          1 c2 v21
  16.          2 c2 v22
  17.          3 c2
  18.          4 c2 v24

  19.         ID CN CV
  20. ---------- -- ----------

  21.          5 c2
  22.          6 c2
  23.          7 c2
  24.          1 c3 v31
  25.          2 c3
  26.          3 c3 v33
  27.          4 c3 v34
  28.          5 c3
  29.          6 c3 v35
  30.          7 c3

  31. 已選擇21行。
2)MODEL
適用範圍:10g及以後

點選(此處)摺疊或開啟

  1. SQL> SELECT id, cn, cv FROM t_col_row
  2.   2 MODEL
  3.   3 RETURN UPDATED ROWS
  4.   4 PARTITION BY (ID)
  5.   5 DIMENSION BY (0 AS n)
  6.   6 MEASURES ('xx' AS cn,'yyy' AS cv,c1,c2,c3)
  7.   7 RULES UPSERT ALL
  8.   8 (
  9.   9 cn[1] = 'c1',
  10.  10 cn[2] = 'c2',
  11.  11 cn[3] = 'c3',
  12.  12 cv[1] = c1[0],
  13.  13 cv[2] = c2[0],
  14.  14 cv[3] = c3[0]
  15.  15 )
  16.  16 ORDER BY ID,cn;

  17.         ID CN CV
  18. ---------- -- ---

  19.          1 c1 v11
  20.          1 c2 v21
  21.          1 c3 v31
  22.          2 c1 v12
  23.          2 c2 v22
  24.          2 c3
  25.          3 c1 v13
  26.          3 c2
  27.          3 c3 v33
  28.          4 c1
  29.          4 c2 v24

  30.         ID CN CV
  31. ---------- -- ---

  32.          4 c3 v34
  33.          5 c1 v15
  34.          5 c2
  35.          5 c3
  36.          6 c1
  37.          6 c2
  38.          6 c3 v35
  39.          7 c1
  40.          7 c2
  41.          7 c3

  42. 已選擇21行。

3)collection
適用範圍:8i,9i,10g及以後版本
要建立一個物件和一個集合:

點選(此處)摺疊或開啟

  1. SQL> create type cv_pair as object(cn varchar2(10),cv varchar2(10));
  2.   2 /

  3. 型別已建立。

  4. SQL> create type cv_varr as varray(8) of cv_pair;
  5.   2 /

  6. 型別已建立。

  7. SQL> select id,t.cn as cn,t.cv as cv
  8.   2 from t_col_row,
  9.   3 table(cv_varr(cv_pair('c1',t_col_row.c1),
  10.   4 cv_pair('c2',t_col_row.c2),
  11.   5 cv_pair('c3',t_col_row.c3)))t
  12.   6 order by 1,2;

  13.         ID CN CV
  14. ---------- ---------- ----------

  15.          1 c1 v11
  16.          1 c2 v21
  17.          1 c3 v31
  18.          2 c1 v12
  19.          2 c2 v22
  20.          2 c3
  21.          3 c1 v13
  22.          3 c2
  23.          3 c3 v33
  24.          4 c1
  25.          4 c2 v24

  26.         ID CN CV
  27. ---------- ---------- ----------

  28.          4 c3 v34
  29.          5 c1 v15
  30.          5 c2
  31.          5 c3
  32.          6 c1
  33.          6 c2
  34.          6 c3 v35
  35.          7 c1
  36.          7 c2
  37.          7 c3

  38. 已選擇21行。

注:11g之後,又出了個listagg分析函式,更容易實現列轉行,由於本機裝的是10g,無法測試,先附一段網上的程式碼吧。

點選(此處)摺疊或開啟

  1. with temp as(
  2.   select 'China' nation ,'Guangzhou' city from dual union all
  3.   select 'China' nation ,'Shanghai' city from dual union all
  4.   select 'China' nation ,'Beijing' city from dual union all
  5.   select 'USA' nation ,'New York' city from dual union all
  6.   select 'USA' nation ,'Bostom' city from dual union all
  7.   select 'Japan' nation ,'Tokyo' city from dual
  8. )
  9. select nation,listagg(city,',') within GROUP (order by city)
  10. from temp
  11. group by nation



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21251711/viewspace-1066741/,如需轉載,請註明出處,否則將追究法律責任。

相關文章