摘要:(简要介绍Oracle11g sql的新功能 pivot/unpivot 的使用方法以及如何使用它们做到行列转换.

蓄势以久的Oracle 11g 终于七月敲锣打鼓隆重推出,接下来就是网上漫天盖地的新功能介绍。11g面向开发的新功能本来就不多,掰着手指头也就是pivot和查询结果缓存的新Hint。本以为不久就会有人详述,谁知盼到两眼欲穿,大家还是翻来覆去的讨论DBA的自动分区之类。Oracle自己的门脸上到是每每用客气的冷漠写着“马上就来” (coming soon),可这马上都转眼都快马上了一个月了,还迟迟不见盖头掀起来。

(http://www.oracle.com/technology/pub/articles/oracle-database-11g-top-features/index.html?RSSid=RSS_otn_articles)

伟人说过“自己动手,丰衣足食”,等不来,咱就自己来。没吃过猪肉,还没见过猪跑?说干就干,下载安装再加一本“sql参考手册”,齐了。这新花活到底怎么使,且听我从头道来。。。

1. 11g以前的行列转换

领袖又说了:“温故而知新”。那就让我们先看看11g以前是怎么实现地。行列转换一直当作甄别老手和新手的试金石,面试的时候面试官不问这个都不好意思张嘴。Itpub的Oracle开发版更是每隔十天半个月就有人问这个,你说重要不重要。

假设有表emp_phone如下:

NAME TYPE PHONE

张三 1 1234-5678

张三 2 4567-7890

张三 3 6000-1001

李四 1 2123-1237

李四 3 6001-5600

马五u 1 3248-1378

马五 2 3423-3948

王二(没麻子) 2 2890-1245

。。。

表里放着张三李四王二麻子等等主人翁的电话号码。(TYPE 1/2/3分别对应家/办公室/手机)。如果要把每个人的所有电话放在一行上,就是行转列了。结果如下:

NAME HOME OFFICE MOBILE

张三 1234-5678 4567-7890 6000-1001

李四 2123-1237 6001-5600

马五 3248-1378 3423-3948

王二(没麻子) 2890-1245

写这个sql的技巧就是按姓名分组,然后使每一组每一类的电话号码最多只有一个,里边用到的分组函数都是聋子的耳朵-摆设。用MAX可以,MIN也行。

这个查询写出来就是:

SELECT

name,

MAX(decode(type,1,phone)) Home,2,phone)) Office,3,phone)) Mobile

FROM

emp_phone

GROUP BY

Name

那位看官说了:“能不能再变回去?”能,不能戏法不就漏了不是?

这儿要用到另一的技巧就是笛卡尔乘积,将一行复制成三行,每一行取一个类型的电话

偷个懒儿把上边的结果表叫emp_phone_x,把列还原成行的sql:

SELECT

NAME,

DECODE (lvl,home,office,mobile) phone

FROM

emp_phone_x,

(SELECT LEVEL lvl

FROM DUAL

CONNECT BY LEVEL <= 3)

WHERE

DECODE (lvl,mobile) IS NOT NULL /

转来转去,一来一往,阴阳辟易,详推用意终何在,延年益寿不老春。往玄里说,就是老祖宗老挂在嘴边上的“道”。那位又说了:“这都哪儿跟哪儿啊?怎么扯到太极拳上去了”。

2. 11g 自带的行列转换

旁边那个带眼镜,说的就是你,眼珠子直勾勾的怎么了?上面的没看懂? 要是以前,我老先生就得语重心长地教育你,那么重要的东西没看懂,将来想不想换工作了?但现在这话就说不出口了,因为11g的sql自己就带这个了。

11g在SELECT语句中新加了关键词PIVOT和UNPIVOT,用这两个关键词,重写上面的两个查询,就变成这个样子的了:

行变列:

SELECT * FROM emp_phone

PIVOT (

MAX(phone) for type IN (1 as home,2 as office,2 as mobile)

)

PIVOT以后的字句都是新加的。但万变不离其宗,还是要用到分组函数。IN后边是按type的不同值映射成不同的列。简单吧?

列变行,这是UNPIVOT的工作,写法如下: SELECT * FROM emp_phone_x UNPIVOT ( phone FOR type in (HOME AS 1,OFFICE AS 2,MOBILE AS 3) ) / 这里是把不同的列转换成不同的type的数值。再用SCOTT用户里的EMP表做个例子,列出各部门之间工资总和: SELECT * FROM ( (SELECT sal,deptno FROM emp) PIVOT ( SUM(sal) FOR deptno IN (10 as dept_10,20 as dept_20,30 as dept_30) ) ) / DEPT_10 DEPT_20 DEPT_30 ---------- ---------- ---------- 8750 10875 9400

再往深里想,前边的所有例子都有一个局限,电话的type和emp的deptno都是有限的、可穷举的。如果这些列都是可随时可添加的,又该怎么办呢?11g以前肯定是要动用动态sql的法宝。那11g又是怎么处理的呢?刚看sql参考手册的时候,看到里边豁然写着IN后边可以接子查询或ANY,当时是佩服的眼泪哗哗的,迫不及待赶紧试一试:

SELECT * FROM

(

(SELECT sal,deptno FROM emp)

PIVOT (

SUM(sal) FOR deptno IN (SELECT deptno FROM dept)

)

)

/

ERROR at line 5:

ORA-00936: missing expression

SELECT * FROM

(

(SELECT sal,deptno FROM emp)

PIVOT (

SUM(sal) FOR deptno IN (ANY)

)

)

/

ERROR at line 5:

ORA-00936: missing expression

这一下又变成拔凉拔凉的,这么大个ORACLE也不能无耻到这个地步吧?正准备再确认一下手册,抓他个人赃俱获,突然有发现里边豁然写着: A subquery is used only in conjunction with the XML keyword… The ANY keyword is used only in conjunction with the XML keyword… 学习不认真,该打。原来是给生成XML串用的,正确用法如下: SELECT * FROM ( (SELECT sal,deptno FROM emp) PIVOT XML ( SUM(sal) FOR deptno IN (ANY) ) ) 1087502010875309400

这个东西的结果具体怎么用就留给大家做作业了。反正XML咱也不熟,借这个机会就下了。。。

2012-11-2922:51:21 我自己的测试

注意:建表插入的时候varchar字符型必须要加上'',

insert into s1 values('yuan',english80);

注意这里max的是分数,in的是subject

返回来

SELECT * FROM

( FROMs1

PIVOT (MAX(score) for subject IN( chinese' chinese,0); line-height:1.5!important">math' math,0); line-height:1.5!important">'english ) ) )

UNPIVOT ( scoreFOR subject IN ( chinese,math,english ) )

注意这里 最后一句的in chinese 之类,chinese不需要加''

成绩表(CHENGJI)如下:

XINGMING

KEMU

CHENGJI

1

张三

语文

89.00

2

张三

数学

98.00

3

张三

英语

88.00

4

李四

语文

90.00

5

李四

数学

89.00

6

李四

英语

60.00

7

王五

数学

66.00

8

王五

英语

99.00

方法一、DECODE

SELECTCJ.XINGMING,

SUM(DECODE(CJ.KEMU,'语文',CJ.CHENGJI,0))语文,'数学',0))数学,'英语',0))英语

FROMCHENGJICJ

GROUPBYCJ.XINGMING

XINGMING

语文

数学

英语

1

张三

89

98

88

2

王五

0

66

99

3

李四

90

89

60

方法二、CASE WHEN

SUM(CASEWHENCJ.KEMU='语文'THENCJ.CHENGJIELSE0END)语文,85); font-weight:bold">WHENCJ.KEMU='数学'END)数学,85); font-weight:bold">WHENCJ.KEMU='英语'END)英语

XINGMING

语文

数学

英语

1

张三

89

98

88

2

王五

0

66

99

3

李四

90

89

60

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

unpivot行转列 oracle,oracle-行转列点评oracle11g sql新功能pivot/unpivot相关推荐

  1. oracle unpivot 用法,PIVOT/UNPIVOT的用法

    转贴: SQL Server2005引入了很多迎合开发者口味的新特性,虽然改动不大,却大大了减少了开发者的工作量,这种替用户考虑的开发思路,值得称赞. 在SQL Server2000中,要实现行列转换 ...

  2. JAVA异常记录(ORA-56900:pivot|unpivot 操作内不支持绑定变量)

    JAVA中ORA-56900: pivot|unpivot 操作内不支持绑定变量 ORA-56900: pivot|unpivot 操作内不支持绑定变量 使用场景及遇到问题 解决方法:在java中拼好 ...

  3. SQL Server 2005之PIVOT/UNPIVOT行列转换

    SQL Server 2005之PIVOT/UNPIVOT行列转换 作者: NinGoo(http://ningoo.itpub.net) 发表于: 2007.04.18 11:49 分类: SQL ...

  4. SQL Server 2005之PIVOT/UNPIVOT行列转换(转)

    SQL Server2005引入了很多迎合开发者口味的新特性,虽然改动不大,却大大了减少了开发者的工作量,这种替用户考虑的开发思路,值得称赞. 在SQL Server2000中,要实现行列转换,需要综 ...

  5. SQL 行转列 列转行 Oracle转置函数函数pivot、unpivot 解决wm_concat 没有排序

    https://www.cnblogs.com/mellowsmile/p/4642306.html HH 终风且暴,顾我则笑,谑浪笑敖,中心是悼. 终风且霾,惠然肯来,莫往莫来,悠悠我思. 博客园 ...

  6. unpivot行转列 oracle,Oracle列转行_unpivot

    Oracle列转行_unpivot 在实际业务开发环境中,我们经常会遇到要对查询的数据集进行列转行的需求.那么Oracle是如何实现的呢?本文也将通过几个实例来详细讲解一下. Oracle列转行 Or ...

  7. oracle sql列转行_ORACLE 列转行和行转列的SQL和函数

    本文介绍两种行.列转换方法,一种是常规的SQL,一种是ORACLE 11G提供的函数.下面使用一个小例子对这两种方法进行说明. ---------------------------------原始表 ...

  8. oracle系列–行转列、列转行

    oracle行转列.oracle列转行 以及 mysql列转行,mysql行转列 文章目录 前言 一.oracle:逗号分隔的一列转行 二.oracle:多列转行 unpivot 函数 三.oracl ...

  9. oracle 动态sql列转行_Oracle 行转列 动态出转换的列

    10月的第二天,前天写了个Oracle中行转列的pivot的基本使用方法,然后,因为pivot的用法中,正常情况下,我们需要转出多少个列,都得在我们的sql中完完整整地写出,而不能直接在里面写个查询来 ...

  10. 设置oracle每行显示字符个数,Oracle一列的多行数据拼成一行显示字符-Oracle

    Oracle一列的多行数据拼成一行显示字符 oracle 提供了两个函数WMSYS.WM_CONCAT 和 ListAgg函数. www.2cto.com 先介绍:WMSYS.WM_CONCAT 例: ...

最新文章

  1. Tencent云联网灾备方案
  2. VTK:图片之ResizeImage
  3. SQL select查询原理--查询语句执行原则转
  4. 新一代数据库技术在双11中的黑科技
  5. jq设置保留两位小数_如何实现python中format函数保留指定位数的小数?
  6. 用usecase获取需求的方法是否有缺陷,还有什么地方需要改进
  7. 手机html文件转TXT,Html 转换 Txt
  8. P3244 [HNOI2015]落忆枫音
  9. 谷歌 kaptcha 图片验证码
  10. 两种办法解决外网资源下载速度过慢的问题
  11. Vision Assistant Minimum Scree Resolution
  12. 亚马逊卖家运营必备八大工具
  13. 医疗器械安规三项是什么?1、漏电流测试 IEC60950-1 2、电介质强度测试=耐压测试?GB9706 3、保护接地电阻测试=保护接地 ?GB9706
  14. CentOS 7 断电分区表丢失解决方法
  15. SSM框架小项目 ACM周总结管理系统 V1.1 开源
  16. abaqus各种文件说明
  17. 0到9的数字替换成零 到 玖 的 大写汉字的函数
  18. 定义一个三角形类(TRI)及其派生类三角柱体类(COL)。其中三角形类可以计算三角形的面积和周长;三角柱体类可以计算柱体的体积和表面积。其具体要求如下: (1)TRI的成员如下:  私有数据成员 
  19. K8s - 内部域名解析 - 外
  20. [如何在VS code中使用mysql](使用sqltools插件)

热门文章

  1. 如何操作电脑压缩包解压文件?干货技巧!电脑压缩包怎样进行文件解压?
  2. Redis端口为什么是6379?
  3. 面试中面试官问的一些问题总结
  4. 推荐!程序员常用的15个学习交流网站
  5. 怎么取消linux ssh互信,[系统-linux] ssh互信操作
  6. 大话设计模式之爱你一万年:第三章 创建型模式:工厂模式:我想让你坐在宝马里笑:6.工厂模式在Spring框架和JDK源码中的应用
  7. 张冬:OpenPOWER CAPI为什么这么快?(二)
  8. 如何在企业微信中使用微搭低代码
  9. 《嵌入式 - 语音识别TWen-ASR-ONE开发笔记》第5章 TWen-ASR-ONE 串口使用
  10. java5兼容性,兼容性问题 (适用于 UNIX 的 Sun Java Enterprise System 5 发行说明)