下面是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. ribbbitMq 教程,详细

    https://blog.csdn.net/hellozpc/article/details/81436980

  2. JSR303 分組数据验证的使用

    场景:一个Bean ,需要在不同情况下分别做验证 1.依赖:springboot 已经集成 2.定义一个bean (验证对象) import javax.validation.constraints. ...

  3. arguments.callee 和 caller

    arguments arguments它是一个类数组对象,包含着传入函数中的所有参数.虽然 arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,该属性是一个指 ...

  4. WebService与RESTful WebService

    Manual Instruction Document Web Service JAX-WS & JAX-RS Author: Liu Xiang Date: 2018/01/12 1. Su ...

  5. SVM标记学习

    # -*- coding: utf-8 -*- """ Created on Mon Oct 1 09:32:37 2018 @author: ""& ...

  6. Spring BeanUtils简单使用

    引入包 <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-be ...

  7. UI5-学习篇-14-基于BSP应用部署Fiori Launchpad

    1.UI5应用发布前端服务器 UI5-学习篇-10-本地UI5应用部署到SAP前端服务器 2.登录Fiori https://XXXXXX:50000/sap/bc/ui5_ui5/sap/arsrv ...

  8. sourcetree 跳过注册

    https://www.cnblogs.com/lucio110/p/8192792.html

  9. 公网Ip和私网ip

    IP可以分为Public IP 和 Private IP,出现这种规划的原因在于IPv4所能表示的IP太少而电脑太多以至于不够用,然而只有Public IP才能直接连接上网络,所以对于那些公司,学校, ...

  10. java学习大方向

    总结Java程序员成长之路   转载  http://bbs.javazhijia.com/topic/1bb0733f80d94aedb50cc3b66d9792b6.html 我也搞了几年JAVA ...