Oracle 多行变一列的方法
2016-02-25 21:21
519 查看
多行变一列的方法有很多,觉得这个第一眼看懂了当时就用的这个办法。
情况是这样的。以下数据前几列是一样的,需要把VAT_VALUE_CHAR 的值放在同一行上。
SELECT *
FROM ps_vat_defaults defaults
WHERE defaults.vat_driver = 'VAT_ENT_RGSTRN'
AND defaults.vat_driver_key1 = 'AMB19'
AND defaults.vat_driver_key2 = 'DEU'
AND vat_default_type IN ('DGS',
'EUGS',
'DSP',
'EUSP');
![](http://images2015.cnblogs.com/blog/580300/201602/580300-20160225211752271-273200044.png)
SELECT VAT_DRIVER
, VAT_DRIVER_KEY1
, VAT_DRIVER_KEY2
, MAX( CASE WHEN VAT_DEFAULT_TYPE = 'DGS' THEN VAT_VALUE_CHAR END ) AS VALUE1
, MAX(CASE WHEN VAT_DEFAULT_TYPE = 'DSP' THEN VAT_VALUE_CHAR END) AS VALUE2
, MAX( CASE WHEN VAT_DEFAULT_TYPE = 'EUGS' THEN VAT_VALUE_CHAR END) AS VALUE3
, MAX(CASE WHEN VAT_DEFAULT_TYPE = 'EUSP' THEN VAT_VALUE_CHAR END) AS VALUE4
FROM ps_vat_defaults defaults
WHERE defaults.vat_driver = 'VAT_ENT_RGSTRN'
AND vat_default_type IN ('DGS', 'EUGS', 'DSP', 'EUSP')
GROUP BY VAT_DRIVER, VAT_DRIVER_KEY1, VAT_DRIVER_KEY2
![](http://images2015.cnblogs.com/blog/580300/201602/580300-20160225211536208-1596913077.png)
wm_concat函数据说是10g之后才有的。他可以把某个字段一列的所有值用逗号分隔的形式放在一个cell里。
SELECT to_char(SUBSTR( wm_concat(VAT_VALUE_CHAR), 0,80))VAT_VALUE_CHAR from ps_vat_defaults defaults where defaults.vat_driver = 'VAT_ENT_RGSTRN' AND defaults.vat_driver_key1='AMB19' AND defaults.vat_driver_key2='NLD' AND vat_default_type in ( 'DGS','EUGS','DSP','EUSP')
结果是一行一列(SAL,PURC,ECSL,ECPR
![](http://images.cnitblog.com/blog/689600/201412/022351417014458.jpg)
![](http://images.cnitblog.com/blog/689600/201412/022352189517544.jpg)
2.一行数据行转列
![](http://images.cnitblog.com/blog/689600/201412/030009101082963.jpg)
![](http://images.cnitblog.com/blog/689600/201412/030009334052446.jpg)
3.结果集转换成一行
![](http://images.cnitblog.com/blog/689600/201412/030019265307076.jpg)
4.把结果集转换成多行
--每种职位一列,得到下面的结果集 (每种职业的列里面有多余的 NULL,如果使用MAX的话,一列只会取一条最大的值了)
![](http://images.cnitblog.com/blog/689600/201412/030030059054244.jpg)
情况是这样的。以下数据前几列是一样的,需要把VAT_VALUE_CHAR 的值放在同一行上。
SELECT *
FROM ps_vat_defaults defaults
WHERE defaults.vat_driver = 'VAT_ENT_RGSTRN'
AND defaults.vat_driver_key1 = 'AMB19'
AND defaults.vat_driver_key2 = 'DEU'
AND vat_default_type IN ('DGS',
'EUGS',
'DSP',
'EUSP');
![](http://images2015.cnblogs.com/blog/580300/201602/580300-20160225211752271-273200044.png)
SELECT VAT_DRIVER
, VAT_DRIVER_KEY1
, VAT_DRIVER_KEY2
, MAX( CASE WHEN VAT_DEFAULT_TYPE = 'DGS' THEN VAT_VALUE_CHAR END ) AS VALUE1
, MAX(CASE WHEN VAT_DEFAULT_TYPE = 'DSP' THEN VAT_VALUE_CHAR END) AS VALUE2
, MAX( CASE WHEN VAT_DEFAULT_TYPE = 'EUGS' THEN VAT_VALUE_CHAR END) AS VALUE3
, MAX(CASE WHEN VAT_DEFAULT_TYPE = 'EUSP' THEN VAT_VALUE_CHAR END) AS VALUE4
FROM ps_vat_defaults defaults
WHERE defaults.vat_driver = 'VAT_ENT_RGSTRN'
AND vat_default_type IN ('DGS', 'EUGS', 'DSP', 'EUSP')
GROUP BY VAT_DRIVER, VAT_DRIVER_KEY1, VAT_DRIVER_KEY2
![](http://images2015.cnblogs.com/blog/580300/201602/580300-20160225211536208-1596913077.png)
wm_concat函数据说是10g之后才有的。他可以把某个字段一列的所有值用逗号分隔的形式放在一个cell里。
SELECT to_char(SUBSTR( wm_concat(VAT_VALUE_CHAR), 0,80))VAT_VALUE_CHAR from ps_vat_defaults defaults where defaults.vat_driver = 'VAT_ENT_RGSTRN' AND defaults.vat_driver_key1='AMB19' AND defaults.vat_driver_key2='NLD' AND vat_default_type in ( 'DGS','EUGS','DSP','EUSP')
结果是一行一列(SAL,PURC,ECSL,ECPR
oracle 行列互转(来自www.askoracle.org整理)
1.使用case when 列转行![](http://images.cnitblog.com/blog/689600/201412/022351417014458.jpg)
SELECT NAME, MAX(CASE WHEN COURSE='语文' THEN SCORE END) "语文", MAX(CASE WHEN COURSE='数学' THEN SCORE END) "数学", MAX(CASE WHEN COURSE='英语' THEN SCORE END) "英语", MAX(CASE WHEN COURSE='物理' THEN SCORE END) "物理", SUM(SCORE) "总分" FROM stu GROUP BY NAME;
![](http://images.cnitblog.com/blog/689600/201412/022352189517544.jpg)
2.一行数据行转列
![](http://images.cnitblog.com/blog/689600/201412/030009101082963.jpg)
SELECT NAME, CASE WHEN LV = 1 THEN '语文' --常量 WHEN LV = 2 THEN '数学' --常量 WHEN LV = 3 THEN '英语' --常量 WHEN LV = 4 THEN '物理' --常量 END 科目, CASE WHEN LV = 1 THEN langu --列名 WHEN LV = 2 THEN math--列名 WHEN LV = 3 THEN english--列名 WHEN LV = 4 THEN pycial--列名 END 成绩 FROM ( SELECT * FROM course, (SELECT LEVEL LV FROM DUAL CONNECT BY LEVEL <= 4) ) --成绩对应的列数 ORDER BY 1, 2;
![](http://images.cnitblog.com/blog/689600/201412/030009334052446.jpg)
3.结果集转换成一行
--查询每个部门的人数 SELECT DEPTNO, COUNT(1) CN FROM EMP GROUP BY DEPTNO ORDER BY 1;
![](http://images.cnitblog.com/blog/689600/201412/030019265307076.jpg)
--将上面的结果转为一行,可以使用 SUM 或者 COUNT 来求出。 SELECT SUM(CASE WHEN DEPTNO = 10 THEN 1 END) D_10, SUM(CASE WHEN DEPTNO = 20 THEN 1 END) D_20, SUM(CASE WHEN DEPTNO = 30 THEN 1 END) D_30 FROM EMP; --也可以使用下面的方法。 SELECT CASE WHEN DEPTNO = 10 THEN CN END D_10, CASE WHEN DEPTNO = 20 THEN CN END D_20, CASE WHEN DEPTNO = 30 THEN CN END D_30 FROM (SELECT DEPTNO, COUNT(1) CN FROM EMP GROUP BY DEPTNO); --和刚讲的一样,生成了三行三列数据,使用 MAX 来获取。 SELECT MAX(CASE WHEN DEPTNO = 10 THEN CN END) D_10, MAX(CASE WHEN DEPTNO = 20 THEN CN END) D_20, MAX(CASE WHEN DEPTNO = 30 THEN CN END) D_30 FROM (SELECT DEPTNO, COUNT(1) CN FROM EMP GROUP BY DEPTNO);
4.把结果集转换成多行
--每种职位一列,得到下面的结果集 (每种职业的列里面有多余的 NULL,如果使用MAX的话,一列只会取一条最大的值了)
![](http://images.cnitblog.com/blog/689600/201412/030030059054244.jpg)
SELECT MAX(CASE JOB WHEN 'CLERK' THEN ENAME END) CLERK, MAX(CASE JOB WHEN 'ANALYST' THEN ENAME END) ANALYST, MAX(CASE JOB WHEN 'MANAGER' THEN ENAME END) MANAGER, MAX(CASE JOB WHEN 'PRESIDENT' THEN ENAME END) PRESIDENT, MAX(CASE JOB WHEN 'SALESMAN' THEN ENAME END) SALESMAN FROM (SELECT ENAME, JOB, --每组都是从 1 开始排序,而每列里面只有一组有数据。也就是 RN 相同的在每列里面只有一条数据 ROW_NUMBER() OVER(PARTITION BY JOB ORDER BY ENAME) RN FROM EMP) GROUP BY RN ORDER BY RN;
相关文章推荐
- 傻瓜式安装ORACLE
- Oracle小知识,用得到!
- Oracle如何定时启动job
- oracle 跟踪事件 set event
- oracle数据库中varchar类型字段中存放的有数字和汉字情况,比较大小问题解决
- oracle语句整理,方便自己查看。
- Oracle自定义函数(不断更新)
- Oracle操作的一些环境变量的设置
- Oracle索引的介绍和使用
- MySQL与Oracle 差异比较之函数
- ArcSDE服务启动 No execute privilege for required Oracle builtin package DBMS_PIPE
- Oracle 一些常用函数
- Oracle触发器 慕课网学习笔记
- 老李分享:Oracle数据库内存参数调优技术
- oracle11G 安装
- IE8.0登录Oracle EBS后报Oracle error 1403错
- Oracle11G 在线重定义
- Oracle中sql的基本使用
- Oracle分区表
- Oracle SQL性能优化