下面是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 
需要变为 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. JAVA获取文件夹下所有的文件

    package com.test; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; im ...

  2. 23.模拟登录cookies请求速询网站数据

    采集速询网站数据: 网站地址:http://www.suxun0752.com/index.html 网站是需要账号登录才给返回信息的,我这里是直接拿的登录后的cookies请求的数据,cookies ...

  3. 《GPU高性能编程CUDA实战》第五章 线程并行

    ▶ 本章介绍了线程并行,并给出四个例子.长向量加法.波纹效果.点积和显示位图. ● 长向量加法(线程块并行 + 线程并行) #include <stdio.h> #include &quo ...

  4. stage的划分

    stage的划分是以shuffle操作作为边界的,遇到一个宽依赖就分一个stage 一个Job会被拆分为多组Task,每组任务被称为一个Stage就像Map Stage, Reduce Stage.S ...

  5. journalctl

    systemd 提供了自己的日志系统(logging system),称为 journal.使用 systemd 日志,无需额外安装日志服务(syslog).读取日志的命令: # journalctl ...

  6. kotlin学习(二)——类

    Kotlin中的类遵循一个简单的结构.尽管与Java有一点细微的差别.你可以使用try.kotlinlang.org在不需要一个真正的项目和不需要部署到机器的前提下来测试一些简单的代码范例. 1. 怎 ...

  7. Flex学习笔记-皮肤

    1文件结构 MXML应用程序 index.mxml 皮肤文件 components.button.skin.btnSkin1.mxml  皮肤文件的组件随便引用了spark.components.Bu ...

  8. cors跨域问题

    同源策略: 是由NetScape提出的著名的安全策略,所有支持javaScript的浏览器都使用这个策略.同源策略限制了一个源中加载文本或脚本与来自其它源中资源的交互方式. IE特例: 授信范围(Tr ...

  9. gitlab入门

    目录 git下载 注册ssh git客户端及图形化工具tortoisegit下载: git客户端安装: https://git-scm.com/download   (git客户端 此种需要命令行执行 ...

  10. Etcd源码解析(转)

    7 Etcd服务端实现 7.1 Etcd启动 Etcd有多种启动方式,我们从最简单的方式入手,也就是从embed的etcd.go开始启动,最后会启动EtcdServer. 先看看etcd.go中的启动 ...