您的位置:首页 > 数据库 > Oracle

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

2015-07-02 00:07 603 查看
在报表的开发当中,难免会遇到行转列的问题。

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

scott的emp的原始数据为:
EMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO
7369SMITHCLERK790212/17/1980800.0020
7499ALLENSALESMAN76982/20/19811600.00300.0030
7521WARDSALESMAN76982/22/19811250.00500.0030
7566JONESMANAGER78394/2/19812975.0020
7654MARTINSALESMAN76989/28/19811250.001400.0030
7698BLAKEMANAGER78395/1/19812850.0030
7782CLARKMANAGER78396/9/19812450.0010
7788SCOTTANALYST75664/19/19873000.0020
7839KINGPRESIDENT11/17/19815000.0010
7844TURNERSALESMAN76989/8/19811500.000.0030
7876ADAMSCLERK77885/23/19871100.0020
7900JAMESCLERK769812/3/1981950.0030
7902FORDANALYST756612/3/19813000.0020
7934MILLERCLERK77821/23/19821300.0010
使用“行转列”统计各职位的人员在各部门的分布人数后,数据为:
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: