Oracle 多行合并一行 方法

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

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



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

1.自定义函数实现 

Sql代码  
  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.   
  20. SQL> select i,my_concat(i) from t group by i;  
  21.   
  22.          I MY_CONCAT(I)  
  23. ---------- --------------------  
  24.          1 d,b,a  
  25.          2 z,t  



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

2.使用sys_connect_by_path 

Sql代码  
  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 
这个函数也可以实现类似的行列转换需求,但是似乎没有办法做到直接根据另外一列排序,所以需要先通过子查询或者临时表排好序: 

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


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

转载于:https://www.cnblogs.com/rongfengliang/p/3867826.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/273648.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 简单入门(一)

Docker 简介 Docker是一个开源的容器引擎,它有助于更快地交付应。Docker可将应用程序和基础设施层隔离,并且能将基础设施当作程序-样进行管理。使用Docker,可更快地打包、测试以及部署应用程序,并可以缩短从编写到部署运行代码的周期。 Docke…

PDF解决方案(2)--文件转PDF

相关专题链接: PDF解决方案(1)--文件上传 PDF解决方案(2)--文件转PDF PDF解决方案(3)--PDF转SWF PDF解决方案(4)--在线浏览 前言:上一篇中讲到的文件上传&…

Docker 常用命令(二)

Docker 镜像常用命令 搜索镜像 可使用 docker search 命令搜索存放在 Docker Hub 中的镜像。例如: docker search java 执行该命令后, Docker 就会在 Docker Hub 中搜索含有 java 这个关键词的镜像仓库。执行该命令后,可看到类似于如下的表格…

Docker 使用Dockerfile构建Docker(三)

Dockerfile 简单使用 先来编写一个最简单的 Dockerfile。 例如&#xff1a; FROM nginx RUN echo <h1>使用Dockerfile构建镜像</h1> > /usr/share/nginx/html/index.html 该 Dockerfile 非常简单&#xff0c;其中的 FORM 、 RUN 都是 Dockerfile 的指令。 FROM …

网络流之最大流问题

Reference&#xff1a; http://blog.csdn.net/rrerre/article/details/6751520 http://blog.csdn.net/y990041769/article/details/21026445 http://www.nocow.cn/index.php/Translate:USACO/NetworkFlow 最大流Edmonds_Karp算法模板&#xff1a; EK算法即增广路算法。 最大流最…

delphi读取excel

简单的例子 1 procedure TForm1.Button1Click(Sender: TObject);2 var3 ExcelApp,MyWorkBook: OLEVariant;4 begin5 opendialog1.Filter:Microsoft Excel Workbook (*.xls)|*.XLS|; 6 edit2.Text : sheet1;7 if opendialog1.Execute then8 begin9 edit1.Text:o…

Docker-compose 常用命令及网络设置(五)

Docker Compose 常用命令 build 构建或重新构建服务。服务被构建后将会以 project_service的形式标记,例如:comoretest db。help 査看指定命令的帮助文档,该命令非常实用。 docker-compose所有命令的帮助文档都可通过该命令查看。 docker-compose he lp COMMAND 示例 docker-co…

浅谈 trie树 及其实现

定义&#xff1a;又称字典树&#xff0c;单词查找树或者前缀树&#xff0c;是一种用于快速检索的多叉树结构&#xff0c; 如英文字母的字典树是一个26叉树&#xff0c;数字的字典树是一个10叉树。 核心思想&#xff1a;是空间换时间.利用字符串的公共前缀来降低查询时间的开销以…

Docker-compose 安装与基本使用(四)

安装 Docker-Compose Compose有多种安装方式,例如通过 shell, pip以及将 Compose作为容器安装等。本次安装以Shell 为主。 通过以下命令自动下载并安装适应系统版本的 Compose: curl -L "https://github.com/docker/compose/releases/download/1.10.0/docker-compose-$(un…

如何开始DDD(完)

连续写了两篇文章&#xff0c;这一篇我想是序的完结篇了。结合用户注册的例子再将他简单丰富一下。在这里只添加一个简单需求&#xff0c;就是用户注册成功后给用户发一封邮件。补充一下之前的代码 public class DomainService {public void Register(User user){if (_userRepo…

git pull 报错:Untracked Fles Preventing Merge

场景 使用 git pull 命令更新报错解决 找到对应的文件删除后重新打开项目。

关于string,我今天科普的

今天下午朋友讨论组上讨论一个关于string的问题&#xff0c;问题是这样的&#xff0c;string a"aaa";string ba;a"bbb",为什么测试b的值不改变&#xff1f;之前我看过一个文章&#xff0c;知道肯定不相等&#xff0c;因为引用地址的一系列问题&#xff0c;…

git pull 报错:The following untracked working tree files would be overwritten by merge

场景 使用 git pull 命令更新报错 Updating d652d1c..fa05549 error: The following untracked working tree files would be overwritten by merge:.idea/encodings.xmlPlease move or remove them before you can merge. Aborting 解决 使用 git clean -d -fx 命令即可。

SpringBoot 配置多数据源

项目Git地址&#xff1a;SpringBoot 配置多数据源&#xff1a;Jacob-multi-data-source 准备工作 准备两个数据库(此模块中两个数据库一个为本地 一个为远程&#xff0c;本地为主&#xff0c;远程为从)。然后建表。 #本地库 CREATE TABLE username (id bigint(11) NOT NULL AUT…

HDU 2912

直线关于球的多次反射&#xff0c;求最后一次反射点 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath>using namespace std; const double inf1e10; const double eps1e-8; struct point {doub…

EMVTag系列3《持卡人基本信息数据》

9F61 持卡人证件号 L&#xff1a;2–26 R&#xff08;需求&#xff09;&#xff1a;数据应存在&#xff0c;在读应用数据过程中&#xff0c;终端不检查&#xff1b; (PBOC2.0第五部分中规定)芯片中持卡人姓名 5F20与持卡人姓名扩展9F0B只能使用一个&#xff0c;另一个必须不…

BindingException: Parameter 'XXX' not found. Available parameters are [collection, list]

应业务需求&#xff0c;需要使用到MQ进行数据上传和下发。传递格式为JSON,服务那边下发JSON数组&#xff0c;接收端将JSON数组转换成List集合&#xff0c;调用Mybatis-plus批量添加saveBatch()。提示字段未找到... org.apache.ibatis.exceptions.PersistenceException: ### Er…

JDK 8 新特性 之 default关键字

前言 Jdk1.8之前的接口中只声明方法&#xff0c;方法具体实现应在子类中进行。Jdk1.8打破了这样的用法&#xff1a;接口中可以实现具体的方法体&#xff0c;只需要加上关键字static或者default修饰即可。 default关键字 public interface UserService {//自定义方法void getUse…

headroom.js插件使用方法

1.什么是headroom.js&#xff1f; headroom是用纯Javascript写的插件&#xff0c;用来隐藏和展示页面元素&#xff0c;从而为页面留下更多空间。比如使用headroom能使导航栏当页面下滚时消失&#xff0c;当页面上滚时候又出现。&#xff08;查看效果&#xff09; 2.工作原理 通…

JDK 8 新特性 之 方法引用

概述 方法引用&#xff1a;当要传递给Lambda体的操作&#xff0c;已经有实现的方法了&#xff0c;就可以使用方法引用方法引用&#xff1a;在Lambda的基础上进一步的简化。换句话说&#xff0c;方法引用就是Lambda表达式&#xff0c;也就是函数式接口的一个实例&#xff0c;通过…