Oracle中“行转列”的实现方式

在报表的开发当中,难免会遇到行转列的问题。

 

以Oracle中scott的emp为例,统计各职位的人员在各部门的人数分布情况,就可以用“行转列”:

 

scott的emp的原始数据为:

EMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO
7369SMITHCLERK790212/17/1980800.00 20
7499ALLENSALESMAN76982/20/19811600.00300.0030
7521WARDSALESMAN76982/22/19811250.00500.0030
7566JONESMANAGER78394/2/19812975.00 20
7654MARTINSALESMAN76989/28/19811250.001400.0030
7698BLAKEMANAGER78395/1/19812850.00 30
7782CLARKMANAGER78396/9/19812450.00 10
7788SCOTTANALYST75664/19/19873000.00 20
7839KINGPRESIDENT 11/17/19815000.00 10
7844TURNERSALESMAN76989/8/19811500.000.0030
7876ADAMSCLERK77885/23/19871100.00 20
7900JAMESCLERK769812/3/1981950.00 30
7902FORDANALYST756612/3/19813000.00 20
7934MILLERCLERK77821/23/19821300.00 10

 

使用“行转列”统计各职位的人员在各部门的分布人数后,数据为:

JOB10(DEPTNO)20(DEPTNO)30(DEPTNO)40(DEPTNO)
CLERK1210
SALESMAN0040
PRESIDENT1000
MANAGER1110
ANALYST0200

 

一、经典的实现方式

主要是利用decode函数、聚合函数(如max、sum等)、group by分组实现的

复制代码
select t.job, count(decode(t.deptno, '10', 1)) as "10(DEPTNO)",
       count(decode(t.deptno, '20', 1)) as "20(DEPTNO)",
       count(decode(t.deptno, '30', 1)) as "30(DEPTNO)",
       count(decode(t.deptno, '40', 1)) as "40(DEPTNO)"
  from scott.emp t
  group by t.job;
复制代码

 

 

二、PIVOT

Oracle 11g后,出现PIVOT,更简便地实现“行转列”。使用前,需确定数据库环境大于11g,最好也确认下生产环境的数据库是否大于11g,避免项目后期出现状况。

with tmp_tab as(
    select t.job, t.deptno
      from scott.emp t
)
select * from tmp_tab t pivot(count(1) for deptno in (10, 20, 30, 40));

 

三、PIVOT XML

使用经典的方法和PIVOT方法,DEPTNO的参数是硬编码的。而通过PIVOT XML能解决这一问题,使分列条件可以是动态的。但,输出的是XML的CLOB的格式。目前,Java读取PIVOT XML CLOB貌似比较困难(本人没有成功读取,可见下文描述,如有知晓者,请知悉)。

with tmp_tab as(
    select t.job, t.deptno
      from scott.emp t
)
select * from tmp_tab t pivot xml (count(1) for deptno in (select deptno from scott.dept));

 

然而,当写完上面PIVOT XML滴时候,使用Java读取数据时,却发现读取不了PIVOT XML的CLOB(普通的并且数据相同的CLOB却能正常读取)

努力了几天,亦尝试下载目前最新的OJDBC,但仍然报错。

报错为

  • “Invalid column type: getCLOB not implemented for class oracle.jdbc.driver.T4CNamedTypeAccessor”--ojdbc6.jar

 

作者:Nick Huang博客:http://www.cnblogs.com/nick-huang/本博文为学习、笔记之用,以笔记记录作者学习的知识与学习后的思考或感悟。学习过程可能参考各种资料,如觉文中表述过分引用,请务必告知,以便迅速处理。如有错漏,不吝赐教。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值