假如有如下表,其中各个i值对应的行数是不定的

  1. SQL> select * from t;
  2. I A          D
  3. ---------- ---------- -------------------
  4. 1 b          2008-03-27 10:55:42
  5. 1 a          2008-03-27 10:55:46
  6. 1 d          2008-03-27 10:55:30
  7. 2 z          2008-03-27 10:55:55
  8. 2 t          2008-03-27 10:55:59
  9. --- 要获得如下结果,注意字符串需要按照D列的时间排序:
  10. 1  d,b,a
  11. 2  z,t

这是一个比较典型的行列转换,有好几种实现方法

1.自定义函数实现

  1. create or replace function my_concat(n number)
  2. return varchar2
  3. is
  4. type typ_cursor is ref cursor;
  5. v_cursor typ_cursor;
  6. v_temp varchar2(10);
  7. v_result varchar2(4000):= '';
  8. v_sql varchar2(200);
  9. begin
  10. v_sql := 'select a from t where i=' || n ||' order by d';
  11. open v_cursor for v_sql;
  12. loop
  13. fetch v_cursor into v_temp;
  14. exit when v_cursor%notfound;
  15. v_result := v_result ||',' || v_temp;
  16. end loop;
  17. return substr(v_result,2);
  18. end;
  19. SQL> select i,my_concat(i) from t group by i;
  20. I MY_CONCAT(I)
  21. ---------- --------------------
  22. 1 d,b,a
  23. 2 z,t

虽然这种方式可以实现需求,但是如果表t的数据量很大,i的值又很多的情况下,因为针对每个i值都要执行一句select,扫描和排序的次数和i的值成正比,性能会非常差。

2.使用sys_connect_by_path

  1. select i,ltrim(max(sys_connect_by_path(a,',')),',') a
  2. from
  3. (
  4. select i,a,d,min(d) over(partition by i) d_min,
  5. (row_number() over(order by i,d))+(dense_rank() over (order by i)) numid
  6. from t
  7. )
  8. start with d=d_min connect by numid-1=prior numid
  9. group by i;

从执行计划上来看,这种方式只需要扫描两次表,比自定义函数的方法,效率要高很多,尤其是表中数据量较大的时候: 
 
3.使用wm_sys.wm_concat 
这个函数也可以实现类似的行列转换需求,但是似乎没有办法做到直接根据另外一列排序,所以需要先通过子查询或者临时表排好序:

  1. SQL> select i,wmsys.wm_concat(a) from t group by i;
  2. I WMSYS.WM_CONCAT(A)
  3. ---------- --------------------
  4. 1 b,a,d
  5. 2 z,t
  6. SQL> select i,wmsys.wm_concat(a)
  7. 2  from
  8. 3  (select * from t order by i,d)
  9. 4  group by i;
  10. I WMSYS.WM_CONCAT(A)
  11. ---------- --------------------
  12. 1 d,b,a
  13. 2 z,t

执行计划上看,只需要做一次表扫描就可以了,但是这个函数是加密过的,执行计划并不能显示函数内部的操作。

Oracle 多行合并一行 方法的更多相关文章

  1. oracle多行合并一行

    以上图为例 执行SQL语句: select d.group_id,to_char(wm_concat(d.tag)) from Imglib_Group_Tag d where d.group_id= ...

  2. SQL实现多行合并一行 .

    ORACLE纯SQL实现多行合并一行[转] 项目中遇到一个需求,需要将多行合并为一行.表结构如下:NAME                            Null           Type ...

  3. ORACLE纯SQL实现多行合并一行

    项目中遇到一个需求,需要将多行合并为一行.表结构如下:NAME                            Null           Type---------------------- ...

  4. JS行合并处理方法

    //行合并 function _w_table_rowspan(col){ _w_table_firsttd = ""; _w_table_currenttd = "&q ...

  5. oracle 多行合并为一行

    sys_connect_by_path select i,ltrim(max(sys_connect_by_path(a,',')),',') afrom(select i,a,d,min(d) ov ...

  6. Sql:多行合并一行以及多条数据取时间最早的那条

    有两个导数据的需求,1.一张表里面每一个订单号可能对应多条数据,每个单号返回时间最早的那条. 2.根据条件查询某个字段并按照逗号,合并在一起. 表类似结构如下: 第一条sql:select c.Id, ...

  7. oracle 多行变一行 wmsys.wm_concat

    背景        还是那个问题,部分程序员喜欢用sql解决问题.发现了这个函数,当初真是大喜过望,现在是哭笑不得.10g支持这个函数,11好像不支持了,而且只有oracle支持,其实自己写个通用方法 ...

  8. Oracle PIVOT 行转列方法

    数据库中業種的存储如下图: SELECT * FROM M_TORIHIKISAKI_GYOSYU 其中GYIUSYU_CD字段代表不同的業種 而画面需要实现下图所示样式:(将每条数据的業種横向展开显 ...

  9. Oracle 多行变一行

    https://blog.csdn.net/rainyspring4540/article/details/50231521

随机推荐

  1. Destroy the Colony CodeForces - 1111D (可逆背包,计数)

    大意:给定字符串$s$, 保证长度为偶数, 给定q个询问, 每次询问给定两个位置$x$,$y$, 可以任意交换字符, 要求所有字符$s[x],s[y]$在同一半边, 剩余所有同种字符在同一半边的方案数 ...

  2. AND Graph CodeForces - 987F (状压)

    链接 大意:给定$m$个数, 若$x\&y=0$, 则在$x$与$y$之间连一条无向边. 求无向图的连通块个数 暴力连边显然超时的, 可以通过辅助结点优化连边, 复杂度$O(n2^n)$ #i ...

  3. spfa毒瘤算法

    终于知道怎么卡spfa(不优化)这一毒瘤算法了 下面就是造数据代码,点数才1e5,边数379980 随便测了一组数据: count: 831841219(入队次数) 68917.096 ms(足够t到 ...

  4. 关于一些逗逼函数//atoi,itoa,strtok,strupr,

    reverse(begin,end)  反转容器内容可以是string,char数组,也可以是int型数组...用于反转其中的内容: char *   strtok(cahr *,const char ...

  5. 根据服务端生成的WSDL文件创建客户端支持代码的三种方式

    第一种:使用wsimport是JDK自带的工具,来生成 生成java客户端代码常使用的命令参数说明: 参数 说明 -p 定义客户端生成类的包名称 -s 指定客户端执行类的源文件存放目录 -d 指定客户 ...

  6. 体验异步的终极解决方案-ES7的Async/Await

    阅读本文前,期待您对promise和ES6(ECMA2015)有所了解,会更容易理解.本文以体验为主,不会深入说明,结尾有详细的文章引用. 第一个例子 Async/Await应该是目前最简单的异步方案 ...

  7. spring boot 学习番外篇:超快速项目初始化

    超快速完成 Spring Boot 项目初始化 最近,在浏览 SPRING 官网时,发现一个超级方便的小工具,可以帮助我们快速创建一个 Spring Boot 项目,前提就是你能连接互联网. 依赖 支 ...

  8. SQL Server 调优系列基础篇 - 常用运算符总结

    前言 上一篇我们介绍了如何查看查询计划,本篇将介绍在我们查看的查询计划时的分析技巧,以及几种我们常用的运算符优化技巧,同样侧重基础知识的掌握. 通过本篇可以了解我们平常所写的T-SQL语句,在SQL ...

  9. bzoj1600

    题解: 简单dp 显然不能超过一半 代码: #include<bits/stdc++.h> using namespace std; ][]; int main() { f[][]=; s ...

  10. Oracle 等待事件 db file sequential read

    db file sequential read-数据文件顺序读取 等待事件: "db file sequential read" Reference Note (文档 ID 345 ...