ITPub博客

首页 > 数据库 > Oracle > oracle行列转换-列转行

oracle行列转换-列转行

原创 Oracle 作者:pwz1688 时间:2014-01-03 11:09:50 0 删除 编辑
在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博客 ” ,链接:https://blog.itpub.net/21251711/viewspace-1066741/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2009-03-30

  • 博文量
    106
  • 访问量
    736030