下面是3种方法 
方法1:SYS_CONNECT_BY_PATH , ROW_NUMBER() OVER(PARTITION BY  ..  ORDER BY ..)  , START WITH , CONNECT BY PRIOR 组合使用 
方法2:wmsys.wm_concat 
方法3:listagg(oracle 11g release 2) 用法就像聚合函数一样,通过Group by语句,把每个Group的一个字段,拼接起来.

listagg 语法概述


listagg函数的语法结构如下:
LISTAGG( [,]) WITHIN GROUP (ORDER BY ) [OVER (PARTITION BY )]

listagg虽然是聚合函数,但可以提供分析功能(比如可选的OVER()子句)。使用listagg中,下列中的元素是必须的:

  • 需要聚合的列或者表达式
  • WITH GROUP 关键词
  • 分组中的ORDER BY子句

下面将演示listagg函数使用的例子


例: 
table1 中 1个col1对应多个col2,下面我们需要把col2转置如col2字段值为 



需要变为 2-3-4 这样的格式,并且col2值是不可枚举的有上千或上万种,这样其他有些通过decode方式的转置就不能实现

使用方法1

 SELECT TT.col1,
'-' || ':' ||
TO_CHAR(SUBSTR(MAX(SYS_CONNECT_BY_PATH(TT.col2, '-')), 2)) M
--这里是为了截取掉 SYS_CONNECT_BY_PATH 在第一个值前加的"-"
FROM (SELECT T.col1,
T.col2,
T.col1 + ROW_NUMBER() OVER(PARTITION BY T.col1 ORDER BY T.col2) RN,
ROW_NUMBER() OVER(PARTITION BY T.col1 ORDER BY T.col2) RM
--上面2行用了2次 ROW_NUMBER() 是因为 col1是累加的值所以一个 T.col1 + ROW_NUMBER() 是为了区别不同的分组,ROW_NUMBER() 这个是为了设置递归的起始值,但对于不同的分组都会有这个值"1"所以需要使用2个
FROM table1 T
WHERE /*T.col1 = TO_NUMBER('1013010875782363')*/) TT --注释的部分是我测试用的
START WITH RM = 1
CONNECT BY PRIOR RN + 1 = RN
GROUP BY TT.col1 ;

方法2

select substr(tt.co, 1, length(tt.co) - 1), --去结尾"-"
tt.col1
from (select t.col1, replace(wmsys.wm_concat(t.col2 || '-'), ',', null) co --去掉","
from table1 t
--WHERE T.col1 = TO_NUMBER('1013010875782363')
group by t.col1) tt;

方法3

select population,
nation,
city,
listagg(city,',') within GROUP (order by city) over (partition by nation) rank
from temp

或者

select nation,listagg(city,',') within GROUP (order by city)
from temp
group by nation

第二个虽然简单但是

wmsys.wm_concat对象实现行列转换的方法,这种方法不被Oracle所推荐,因为WMSYS用户用于Workspace Manager,其函数对象可能因版本而不同,这种变化在11.2.0.3及10.2.0.5中体现出来。原本WM_CONCAT函数返回值为VARCHAR2变更为CLOB。这一变化导致了很多程序的异常。 
参考 
http://www.eygle.com/archives/2012/10/wmsys_wm_concat.html

-------20150522 update--------

转置实现
说明:把 TF_B_TRADE_SP 里一个订单的SP增加或减少的 SP_PRODUCT_ID 转置后以一条行记录的形式列出

 SELECT TT.TRADE_ID,
'-' || ',' ||
SUBSTR(MAX(SYS_CONNECT_BY_PATH(TT.SP_PRODUCT_ID, '-')), 2)
FROM (SELECT T.TRADE_ID,
T.SP_PRODUCT_ID,
T.MODIFY_TAG,
T.TRADE_ID + ROW_NUMBER() OVER(PARTITION BY T.TRADE_ID ORDER BY T.SP_PRODUCT_ID) RN,
ROW_NUMBER() OVER(PARTITION BY T.TRADE_ID ORDER BY T.SP_PRODUCT_ID) RM
FROM TF_B_TRADE_SP T
WHERE T.TRADE_ID = TO_NUMBER(:VTRADE_ID)
AND T.MODIFY_TAG IN ('', 'B')) TT
START WITH RM = 1
CONNECT BY PRIOR RN + 1 = RN
GROUP BY TT.TRADE_ID
UNION ALL
SELECT TT.TRADE_ID,
'+' || ',' ||
SUBSTR(MAX(SYS_CONNECT_BY_PATH(TT.SP_PRODUCT_ID, '-')), 2)
FROM (SELECT T.TRADE_ID,
T.SP_PRODUCT_ID,
T.MODIFY_TAG,
T.TRADE_ID + ROW_NUMBER() OVER(PARTITION BY T.TRADE_ID ORDER BY T.SP_PRODUCT_ID) RN,
ROW_NUMBER() OVER(PARTITION BY T.TRADE_ID ORDER BY T.SP_PRODUCT_ID) RM
FROM TF_B_TRADE_SP T
WHERE T.TRADE_ID = TO_NUMBER(:VTRADE_ID)
AND T.MODIFY_TAG IN ('', 'A')) TT
START WITH RM = 1
CONNECT BY PRIOR RN + 1 = RN
GROUP BY TT.TRADE_ID;

修改后最后写好是这样

 SELECT MI.M || ',' || AD.A
FROM (SELECT TT.TRADE_ID,
'-' || ':' ||
TO_CHAR(SUBSTR(MAX(SYS_CONNECT_BY_PATH(TT.SP_PRODUCT_ID, '_')),
2)) M
FROM (SELECT T.TRADE_ID,
T.SP_PRODUCT_ID,
T.MODIFY_TAG,
T.TRADE_ID + ROW_NUMBER() OVER(PARTITION BY T.TRADE_ID ORDER BY T.SP_PRODUCT_ID) RN,
ROW_NUMBER() OVER(PARTITION BY T.TRADE_ID ORDER BY T.SP_PRODUCT_ID) RM
FROM TF_B_TRADE_SP T
WHERE T.TRADE_ID = TO_NUMBER('')
AND T.MODIFY_TAG IN ('', 'B')) TT
START WITH RM = 1
CONNECT BY PRIOR RN + 1 = RN
GROUP BY TT.TRADE_ID) MI,
(SELECT TT.TRADE_ID,
'+' || ':' ||
TO_CHAR(SUBSTR(MAX(SYS_CONNECT_BY_PATH(TT.SP_PRODUCT_ID, '_')),
2)) A
FROM (SELECT T.TRADE_ID,
T.SP_PRODUCT_ID,
T.MODIFY_TAG,
T.TRADE_ID + ROW_NUMBER() OVER(PARTITION BY T.TRADE_ID ORDER BY T.SP_PRODUCT_ID) RN,
ROW_NUMBER() OVER(PARTITION BY T.TRADE_ID ORDER BY T.SP_PRODUCT_ID) RM
FROM TF_B_TRADE_SP T
WHERE T.TRADE_ID = TO_NUMBER('')
AND T.MODIFY_TAG IN ('', 'A')) TT
START WITH RM = 1
CONNECT BY PRIOR RN + 1 = RN
GROUP BY TT.TRADE_ID) AD;

说明

 SELECT TT.col1,
'-' || ':' ||
TO_CHAR(SUBSTR(MAX(SYS_CONNECT_BY_PATH(TT.col2, '-')), 2)) M
--这里是为了截取掉 SYS_CONNECT_BY_PATH 在第一个值前加的"-"
FROM (SELECT T.col1,
T.col2,
T.col1 + ROW_NUMBER() OVER(PARTITION BY T.col1 ORDER BY T.col2) RN,
ROW_NUMBER() OVER(PARTITION BY T.col1 ORDER BY T.col2) RM
--上面2行用了2次 ROW_NUMBER() 是因为 col1是累加的值所以一个 T.col1 + ROW_NUMBER() 是为了区别不同的分组,ROW_NUMBER() 这个是为了设置递归的起始值,但对于不同的分组都会有这个值"1"所以需要使用2个
FROM table1 T
WHERE /*T.col1 = TO_NUMBER('1013010875782363')*/) TT --注释的部分是我测试用的
START WITH RM = 1
CONNECT BY PRIOR RN + 1 = RN
GROUP BY TT.col1 ;

oracle 转置实现的更多相关文章

  1. 行列转置(Oracle)

    一.Oracle行列转置 1.行转列 (1)创建表格.插入测试数据 create table student( id number, name ), course ), score number ) ...

  2. [转]Oracle SQL函数pivot、unpivot转置函数实现行转列、列转行

    原文地址:http://blog.csdn.net/seandba/article/details/72730657 函数PIVOT.UNPIVOT转置函数实现行转列.列转行,效果如下图所示: 1.P ...

  3. Oracle 行列转置

    两种简单的行列转置 1.固定列数的行列转换如student   subject    grade--------- ---------- --------student1  语文       80st ...

  4. 表的转置 行转列: DECODE(Oracle) 和 CASE WHEN 的异同点

    异同点 都可以对表行转列: DECODE功能上和简单Case函数比较类似,不能像Case搜索函数一样,进行更复杂的判断 在Case函数中,可以使用BETWEEN, LIKE, IS NULL, IN, ...

  5. ORACLE的sign函数和DECODE函数

    比较大小函数 sign 函数语法:sign(n) 函数说明:取数字n的符号,大于0返回1,小于0返回-1,等于0返回0 示例:一.select sign( 100 ),sign(- 100 ),sig ...

  6. Oracle DECODE函数的语法介绍

    Oracle DECODE函数功能很强,下面就为您详细介绍Oracle DECODE函数的用法,希望可以让您对Oracle DECODE函数有更多的了解. Oracle DECODE函数 Oracle ...

  7. ORACLE 字符串操作

    1 字符串连接   SQL> select 'abc' || 'def' from dual; 'ABC'|------abcdef 2 小写SQL>select lower('ABC01 ...

  8. Oracle字符串操作[转:http://www.cnblogs.com/xd502djj/archive/2010/08/11/1797577.html]

    ORACLE 字符串操作 1 字符串连接   SQL> select 'abc' || 'def' from dual; 'ABC'|------abcdef 2 小写SQL>select ...

  9. Oracle Sql优化之报表和数据仓库运算

    1.行转列:有两种写法,一种是case when end写法,另一种写法是pivot(oracle 11g新增) select job, then sal end) as sal10, then sa ...

随机推荐

  1. php单图片上传。

    1.input:file form 提交 /** * 用户头像上传 * @param [type] $file 图像信息 */ function domeadd($file){ if (is_arra ...

  2. 编写优秀Bug报告的艺术及案例分析

    编写优秀Bug报告的艺术及案例分析 ---Rex Black原著<Fine art of writing a good bug report > ---Kiki翻译于2005/5/28 前 ...

  3. Android Camera开发:周期性循环自动聚焦auto focus挂掉原因分析(preview is not enabled)

    参考:Android Camera开发:扫描二维码,周期性循环自动聚焦auto focus挂掉原因分析(preview is not enabled) 最近做Android人脸识别时,camera在自 ...

  4. flex学习笔记-日历选择与显示

    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...

  5. PHP数据库基于PDO操作类(mysql)

    这是网上找的关于Mysql的操作类,非常适合初学者使用 <?php class Mysql { protected static $_dbh = null; //静态属性,所有数据库实例共用,避 ...

  6. Oracle函数使用

    数据格式化截取:  Trunc(data,[yyyy]) oracle的特有if判断: decode(sex, 0, '男', 1, '女') 分组排序:row_number() over(parti ...

  7. idea 执行maven 命令

    如果当前账号不是超级管理员,这边需要执行系统用户变量, 输入安装文件bin路径 参考:https://blog.csdn.net/qq_19167629/article/details/7958490 ...

  8. 处理TypeError: Converting circular structure to JSON

    // Demo: Circular reference var o = {}; o.o = o; // Note: cache should not be re-used by repeated ca ...

  9. Todolist功能开发

    一.属性绑定和双向数据绑定: v-bind:title 或简写成 :title实现title属性绑定: v-model实现双向数据绑定(双向是指:当数据变了,input的value会改变:当input ...

  10. 记录git的初始设置,添加文件,提交文件

    1 初始配置 git config --global user.name ""  //配置用户名 git config --global user.email "&quo ...