http://luckysea.itpub.net/post/5481/457746
在 Oracle 数据库 11g 推出之前,您需要针对每个值通过使用decode 函数或case语句进行列转换操作,
并将每个不同的值编写为一个单独的列。但是,该方法不是很不直观也不是很方便。
oracle11g可以使用一种很好的新特性PIVOT和UNPIVOT,通过一种新的操作符以交叉表格式显示任何查询,
oracle为了实现更强大的数据仓库应用,在SQL和PL/SQL方面有很大的加强。
--使用昨天建立的测试表
C:Documents and SettingsAdministrator>sqlplus /nolog
SQL*Plus: Release 11.1.0.6.0 - Production on 星期五 3月 21 09:16:11 2008
Copyright (c) 1982, 2007, Oracle. All rights reserved.
idle>conn / as sysdba
已连接。
PENG11G(sys)>desc vc_test;
名称 是否为空? 类型
----------------------------------------------------- -------- ------------------------------------
PNO VARCHAR2(6)
PNAME VARCHAR2(10)
SALARY NUMBER(10,2)
PLEVEL VARCHAR2(3)
PENG11G(sys)>select * from vc_test;
PNO PNAME SALARY PLE
------ ---------- ---------- ---
000001 张三 1500 PG
000002 李四 2500 SE
000003 王五 4500 SE
000004 周二 1500 PG
000004 刘六 8500 SSE
000006 待定
已选择6行。
PENG11G(sys)>select plevel, count(1) cnt
2 from vc_test
3 where plevel is not null
4 group by plevel;
PLE CNT
--- ----------
SSE 1
PG 2
SE 2
--我们将plevel转换成行
PENG11G(sys)> select * from (
2 select plevel
3 from vc_test t
4 )
5 pivot
6 (
7 count(plevel)
8 for plevel in ('PG','SE','SSE')
9 ) ;
'PG' 'SE' 'SSE'
---------- ---------- ----------
2 2 1
--有 pivot 就应该有unpivot
PENG11G(sys)>create table upv_test as
2 select * from (
3 select plevel
4 from vc_test t
5 )
6 pivot
7 (
8 count(plevel)
9 for plevel in ('PG','SE','SSE')
10 ) ;
表已创建。
PENG11G(sys)>desc upv_test;
名称 是否为空? 类型
----------------------------------------------------- -------- ----------------------
'PG' NUMBER
'SE' NUMBER
'SSE' NUMBER
PENG11G(sys)>select * from upv_test;
'PG' 'SE' 'SSE'
---------- ---------- ----------
2 2 1
PENG11G(sys)>select *
2 from upv_test
3 unpivot
4 (
5 plevel_count
6 for plevel in ("'PG'","'SE'","'SSE'")
7 ) ;
PLEVE PLEVEL_COUNT
----- ------------
'PG' 2
'SE' 2
'SSE' 1