Oracle的行列转换

2014-11-24 18:36:22 · 作者: · 浏览: 4

首先准备如下表格


现在查询各部门各工种的总薪水,


得到结果:


如果要在变回前面的结果,需要用到笛卡尔乘积,一行变五行,然后利用decode。例如:


得到结果:


得到结果:


实际上,oracle对pivot子句中出现的列以外的列做了一个隐式的group by.
现在,如果想要再结果中增加1列,显示部门的薪水总合,可以这么做,


2点说明,
1)oracle对pivot子句中出现的列以外的列,也就是deptno和SAL_TOTAL做了隐式的group by.
这里用了分析函数,对于每个deptno,SAL_TOTAL是唯一的,所以group by的结果还是3行。
2)oracle会拼接列名 = for字句中别名+聚合函数别名,比如'PRESIDENT'+'_'+'SAL_TOTAL'。

可以指定多个聚合函数,例如统计薪水总合和人数总合:


for子句可以指定多列
为此,先给emp表追加1列rank,取值为'A','B',


现在,想统计SALESMAN和CLERK的员工中,rank A和rank B各自的人数。


用unpivot语句来做列到行的转换,


如果加上include nulls子句


转换为行以后,有2列数据分别显示薪水总合和人数总和。也就是需要对2列同时进行转换。


关于ANY子句

pivot的一个不便之处是需要在IN子句中指定所有取值,能不能自动完成呢?
比如for job in (select distinct(job) from emp),可惜oracle不支持这么做。
不过oracle支持通过这种方式返回XML格式数据,例如,


*可以把上面的ANY换成select distinct(job) from emp