Oracle 行列转换

1、固定列数的行列转换

student subject grade
--------- ---------- --------
student1 语文 80
student1 数学 70
student1 英语 60
student2 语文 90
student2 数学 80
student2 英语 100
……
转换为
语文 数学 英语
student1 80 70 60
student2 90 80 100
……
语句如下:select student, 
sum(decode(subject,'语文', grade,null)) "语文",
sum(decode(subject,'数学', grade,null)) "数学",
sum(decode(subject,'英语', grade,null)) "英语"
from table
group by student;
 

2、不定列行列转换

c1 c2
--- -----------
1 我
1 是
1 谁
2 知
2 道
3 不
……
转换为
1 我是谁
2 知道
3 不

这一类型的转换可以借助于PL/SQL来完成,这里给一个例子
CREATE OR REPLACE FUNCTION get_c2(tmp_c1 NUMBER)
RETURN VARCHAR2
IS
Col_c2 VARCHAR2(4000);
BEGIN
FOR cur IN (SELECT c2 FROM t WHERE c1=tmp_c1) LOOP
Col_c2 := Col_c2||cur.c2;
END LOOP;
Col_c2 := rtrim(Col_c2,1);
RETURN Col_c2;
END;

select distinct c1 ,get_c2(c1) cc2 from table;

或者不用pl/sql,利用分析函数和 CONNECT_BY 实现:

SELECT c1, SUBSTR (MAX (SYS_CONNECT_BY_PATH (c2, ';')), 2) NAME
    FROM (SELECT c1, c2, rn, LEAD (rn) OVER (PARTITION BY c1 ORDER BY rn) rn1
            FROM (SELECT c1, c2, ROW_NUMBER () OVER (ORDER BY c2) rn
                    FROM t))
START WITH rn1 IS NULL
CONNECT BY rn1 = PRIOR rn
GROUP BY c1;

3、列数不固定(交叉表行列转置)
这种是比较麻烦的一种,需要借助pl/sql:

原始数据:
CLASS1     CALLDATE         CALLCOUNT
1          2005-08-08       40
1          2005-08-07       6
2          2005-08-08       77
3          2005-08-09       33
3          2005-08-08       9
3          2005-08-07       21

转置后:
CALLDATE     CallCount1 CallCount2 CallCount3
------------ ---------- ---------- ----------
2005-08-09   0          0          33
2005-08-08   40         77         9
2005-08-07  6      0          21

试验如下:
1). 建立测试表和数据
CREATE TABLE t(
    class1 VARCHAR2(2 BYTE),
    calldate DATE,
    callcount INTEGER
);

INSERT INTO t(class1, calldate, callcount)
VALUES ('1', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 40);

INSERT INTO t(class1, calldate, callcount)
VALUES ('1', TO_DATE ('08/07/2005', 'MM/DD/YYYY'), 6);

INSERT INTO t(class1, calldate, callcount)
VALUES ('2', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 77);

INSERT INTO t(class1, calldate, callcount)
VALUES ('3', TO_DATE ('08/09/2005', 'MM/DD/YYYY'), 33);

INSERT INTO t(class1, calldate, callcount)
VALUES ('3', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 9);

INSERT INTO t(class1, calldate, callcount)
VALUES ('3', TO_DATE ('08/07/2005', 'MM/DD/YYYY'), 21);

COMMIT ;

2). 建立ref cursor准备输出结果集 
CREATE OR REPLACE PACKAGE pkg_getrecord
IS
    TYPE myrctype IS REF CURSOR;
END pkg_getrecord;
/

3). 建立动态sql交叉表函数,输出结果集 
CREATE OR REPLACE FUNCTION fn_rs
    RETURN pkg_getrecord.myrctype
IS
    s VARCHAR2 (4000); 
    CURSOR c1 IS
    SELECT ',sum(case when Class1='
            || class1
            || ' then CallCount else 0 end)'
            || ' "CallCount'
            || class1
            || '"' c2
    FROM t
    GROUP BY class1;
    r1 c1%ROWTYPE;
    list_cursor pkg_getrecord.myrctype;
BEGIN
    s := 'select CallDate ';
    OPEN c1;
    LOOP
        FETCH c1 INTO r1;
        EXIT WHEN c1%NOTFOUND;
        s := s || r1.c2;
    END LOOP;
    CLOSE c1;
    s := s || ' from T group by CallDate order by CallDate desc ';
    OPEN list_cursor FOR s;
    RETURN list_cursor;
END fn_rs;
/

4). 测试在sql plus下执行:
var results refcursor;
exec :results := fn_rs;
print results;
CALLDATE        CallCount1 CallCount2 CallCount3
--------------- ---------- ---------- ----------
2005-08-09      0          0          33
2005-08-08      40         77         9
2005-08-07      6          0          21

Oracle 行列转换相关推荐

  1. Oracle 行列转换函数pivot使用

    问题描述: 描述:在项目中,需要将表中日期数据行,用视图转列显示月报表 解决方案: 注意:多聚合必须重命名. create table pivottest( 主键 varchar2(50) defau ...

  2. oracle 总转横函数,详解Oracle行列转换函数-pivot函数和unpivot函数-多智时代

    今天主要介绍一下Oracle行转列及列转行常见函数,下面一起来看看吧! 行列转换 pivot函数:行转列函数 语法:pivot(任一聚合函数 for 需专列的值所在列名 in (需转为列名的值)): ...

  3. Oracle行列转换的思考与总结

    最近几天一直在弄Oracle-SQL的问题,涉及到了一些平时没有用到的东西,也因此而在这里郁闷了好久.现在问题得到了解决虽说不算完美.但是还是和大家一起分享一下. 行列转换之一:sum(case wh ...

  4. Oracle 行列转换总结

    行列转换包括以下六种情况: *列转行 *行转列 *多列转换成字符串 *多行转换成字符串 *字符串转换成多列 *字符串转换成多行 下面分别进行举例介绍. 首先声明一点,有些例子需要如下10g及以后才有的 ...

  5. oracle行列转换总结

    最近论坛很多人提的问题都与行列转换有关系,所以我对行列转换的相关知识做了一个总结, 希望对大家有所帮助,同时有何错疏,恳请大家指出, 我也是在写作过程中学习,算是一起和大家学习吧. 行列转换包括以下六 ...

  6. oracle行列转换关联union的方式_几行代码轻松玩转 Excel 行列转换

    几行代码轻松玩转 Excel 行列转换 下面这种交叉式的 Excel 表是很常见的格式,用来填写和查看都比较方便: 但是,如果想做进一步的统计分析,这种格式就不方便了,需要行列转换,变成如下格式的明细 ...

  7. oracle 的行列转换函数,Oracle行列转换函数

    VM_CONCAT vm_concat可以用来进行行转列,默认以逗号分隔,可通过vm_concat(name,',','|')修改为|1 2 3 4 5 6 7 8 9 10 11 12 13SQL& ...

  8. oracle行列转换

    多行转一行: 表结构: 1  A 1  B 1  C 2  A 2  B 3  C 3  F 4  D 转换后变成: 1  A,B,C 2  A,B 3  C,F 4  D 这个不排序: SELECT ...

  9. [Oracle]行列转换(行合并与拆分)

    使用wmsys.wm_concat 实现行合并 在 Oracle  中, 将某一个栏位的多行数据转换成使用逗号风格的一行显示,可以使用函数  wmsys.wm_concat 达成. 这个在上一篇 or ...

最新文章

  1. python好找工作吗2017-2017学什么编程语言好找工作?
  2. microsoft visual sourcesafe explorer 获取不了文件夹的解决方法
  3. 转: javascript技术栈
  4. ubuntu 在vm中如何上网及注意问题
  5. windows加密和linux加密_Windows系统自带的BitLocker加密方法
  6. linux之xargs使用技巧
  7. 2003下的共享问题
  8. 基于Matpower的电力系统潮流计算原理及仿真设计(详细)
  9. Windows7包含哪些版本
  10. Linux编辑器-vim的使用的 “打字练习“
  11. mysql ibd恢复数据_mysql通过ibd恢复数据
  12. 4D 语义分割——TemporalLidarSeg
  13. Kubernetes详解
  14. REASONING ABOUT ENTAILMENT WITH NEURAL ATTENTION 论文阅读笔记
  15. 已解决:GET http://localhost:8080/statics/js/jquery-3.4.1.js net::ERR_ABORTED 404
  16. HTTP HTTPS SSL TLS
  17. ALevel 自由落体:历史与基本概念
  18. 修改个人资料和头像的协议数据包
  19. arduino交通信号灯
  20. 读1968图灵奖获得者 哈明演讲的感悟

热门文章

  1. 寻找数组变化:树形结构,分治模型
  2. Springcloud中的region和zone的使用
  3. 你多久更新一次简历,决定了你的收入多久能提升
  4. 第一题:Big Countries
  5. SpringMVC拦截器HandlerInterceptor使用
  6. 再次学习mysql优化
  7. Vmware快速安装linux虚拟机(SUSE)
  8. 本案例通过ArrayList集合来显示Collection接口中的共性函数
  9. econtrol窗体设计器
  10. heima Oracle day2